5

我正在阅读 SCJP 指南,发现了以下问题,它看起来很简单,对某些人来说可能很容易。但是,我真的很难找到解决方案。

import java.util.regex.*;

class study{

    public static void main(String[] args) {
      Pattern p = Pattern.compile(args[0]);
      Matcher m = p.matcher(args[1]);
      boolean b=false;
      while(b=m.find()){
      System.out.print(m.start()+" "+m.group());
     }
    }

}

在那个问题中,命令行参数的给出如下

java study "\d*" ab34ef

而且,说输出是什么,我的猜测是334234,它在那个选项中。但是,答案(在 Windows 上)是01234456。所以,我的第一个问题是How ??

现在,人们说,你为什么不尝试。然后,我会说,是的,我做到了。但是,就我而言,我的屏幕上没有任何输出。然后,我试图弄清楚考虑所有类型的输入及其值。

在此处输入图像描述

在上面的屏幕截图中,当我包含System.out.print(args[0]+" "+args[1]);在 main 方法中时,显示了第二个输出。

甚至,我把命令行改成了这个

java study "\\d*" ab34ef

然后,我也没有得到任何输出。所以,任何人都可以解释这一切。

输出==

java study "\d*" ab34ef
No output
java study "\\d*" ab34ef
No output

然后我System.out.print(args[0]+" "+args[1]);在 main 方法中添加。

java study "\d*" ab34ef
\Document and Setting ab34ef
java study "\\d*" ab34ef
\\d* ab34ef

注意:没有输出意味着它没有显示任何内容。

4

4 回答 4

4

实际上发生的情况是,当您\d*作为命令行参数传递时,它被视为\d后跟*通配符。因此,该参数将替换为以该目录开头的所有文件\d。(这种行为发生在Windows。虽然我不知道Linux,因为我没有使用它)。

因此,您没有将正则表达式传递给\d程序,而是以 in 开头的文件/目录名称。

尝试在代码中打印参数:-

System.out.println(args[0] + " : " + args[1]);

这将为您提供一些以开头的文件/目录名称\d...


解决方法: -

如果你想通过正则表达式,你可以使用变通方法。作为正则表达式传递" \d*",前面有一个空格,在你的代码中,使用args[0].trim()orargs[0].replace(" ", "");代替args[0].

因此,将其称为:-

java Foo " \d*" ab34ef

并将您的代码更改为: -

Pattern p = Pattern.compile(args[0].replace(" ", ""));
Matcher m = p.matcher(args[1]);

这将为您完成工作。


现在这就是通过命令行传递正则表达式的问题。

至于为什么要获得该输出,请查看此答案 - string-replaceall-strange-behaviour,这是关于类似问题的。您将了解为什么会发生这种情况。

于 2012-12-20T11:42:41.680 回答
0

我得到了你想要的结果

java study "\d*" ab34ef

但也许尝试相同,如Rohit Jain评论:

java study "\\d*" ab34ef

但它应该适用于您的线路!(在linux上可以,可能是windows问题)

于 2012-12-20T11:23:39.663 回答
0

试试这个。

java study d* ab34ef

这就是为什么。

转义序列适用于 Java 编译器,例如,编译器将看到一个 '\' 后跟一个 'n',并将它们都替换为单个换行符。程序运行时,转义序列对 Java 毫无意义;当它们出现在源代码中时,它们仅对编译器有意义。

将特殊字符嵌入到 Java 程序的参数中实际上根本不是 Java 问题——而是操作系统问题。

如果你想从你的源代码做同样的事情,你必须像下面这样传递字符串。

Pattern p = Pattern.compile("\\d*");
Matcher m = p.matcher("ab34ef");

如果您想通过命令行运行,只需传递不带转义字符即可

 d* ab34ef

使用诸如Eclipse之类的 IDE并进行调试以查找其传递的确切内容。

于 2012-12-20T11:28:57.000 回答
0

要回答您问题的第一部分,正则表达式\d*匹配个或多个数字,即允许匹配的内容之一是空字符串。因此给定输入字符串

ab34ef

模式匹配

  • 位置 0 处的空字符串
  • 位置 1 的空字符串
  • 34位置 2的字符串
  • 位置 4 的空字符串
  • 位置 5 的空字符串
  • 位置 6 的空字符串

这解释了预期的答案。

于 2012-12-20T11:42:00.273 回答