1

我正在编写一个 Java 程序来读取其他 Java 源文件并从中提取import语句:

package com.me.myapp

import blah.example.dog.client.Fizz;
import blah.example.cat.whiskers.client.Buzz;
import blah.example.shared.Foo;
import blah.example.server.Bar;
...etc.

我希望正则表达式返回以包名开头的任何内容import blah.example.client因此,在上面的示例中,正则表达式会选择Fizzand Buzz,但不会选择Fooor Bar

我最好的尝试是:

String regex = "import blah.example*client*";
if(someString.matches(regex))
    // Do something

这个正则表达式没有抛出异常,但它不起作用。我哪里错了?提前致谢!

4

5 回答 5

2

您可以尝试使用^import blah[.]example[.](\\w+[.])*client[.]\\w+;$MULTILINE 标志来使 ^ 和 $ 匹配新行的开始和结束。

这是一些演示:

String data = "package com.me.myapp\n\nimport blah.example.dog.client.Fizz;\nimport blah.example.cat.whiskers.client.Buzz;\nimport blah.example.shared.Foo;\nimport blah.example.server.Bar;";

Pattern p = Pattern.compile(
        "^import blah[.]example[.](\\w+[.])*client[.]\\w+;$",
        Pattern.MULTILINE);
Matcher m = p.matcher(data);
while (m.find())
    System.out.println(m.group());

输出

import blah.example.dog.client.Fizz;
import blah.example.cat.whiskers.client.Buzz;

您还可以使用类似的正则表达式来检查它是否与您的字符串/行匹配

String data = "package com.me.myapp\n\nimport blah.example.dog.client.Fizz;\nimport blah.example.cat.whiskers.client.Buzz;\nimport blah.example.shared.Foo;\nimport blah.example.server.Bar;";

Scanner scanner = new Scanner(data);
while (scanner.hasNextLine()){
    String line=scanner.nextLine();
    if (line.matches("import blah[.]example[.](\\w+[.])*client[.]\\w+;")){
        System.out.println(line);
    }
}
于 2013-08-16T03:07:43.007 回答
2

正则表达式中的点是表示“任何字符”的特殊字符。您必须转义一个文字点,并且您希望在 * 之前有一个点(表示任何字符出现的任意次数):

"import blah\\.example.*client.*"

你有它的表达:

"import blah.example*client*"

意思是“import blah”,后跟一个通配符,然后是“exampl”,然后是 0 个或多个 e,然后是“clien”,然后是 0 个或多个 t。它会匹配,比如“import blahxexampleeeeeclientttt”或“import blah examplelclien”。

此外,(固定的)正则表达式仍将匹配诸如“import blah.example2.notclient”和“/* import blah.example.client; */”之类的内容,因此您仍然希望强制在客户端和行首,例如(为清楚起见未转义,请记住在字符串常量中转义斜杠):

^import blah\.example(\.[^.]+)*\.client(\.[^.]+)*;

其中序列(为清楚起见未转义):

(\.[^.]+)*

匹配任意数量的单个“.xxx”路径组件。

但是请注意,就像 Brad Mace 在评论中指出的那样,单独的正则表达式仍然不可靠。您没有很好的跳过方法,例如,由 /* */ 多行注释注释掉的一堆导入语句。

于 2013-08-16T02:54:33.240 回答
1

假设这someString是Java源代码中的一行

Java 字符串

"import\\s+blah\\.example(?:\\.\\w+)*\\.client(?:\\.\\*|(?:\\.\\w+)*);"

正则表达式

import\s+blah\.example(?:\.\w+)*\.client(?:\.\*|(?:\.\w+)*);
于 2013-08-16T02:59:29.853 回答
1

威胁源作为文本文件可能是有问题的......

我会尝试以下方法: * 使用 javac 处理器框架将匹配器集成到编译器 * 使用 ASM 库

于 2013-08-16T07:19:48.187 回答
0

正则表达式可能会错误地解析 src,例如注释掉导入

/*
import blah.example.dog.client.Fizz;
import blah.example.cat.whiskers.client.Buzz;
*/

或未格式化的代码

import blah.example.dog.client.Fizz; import blah.example.cat.whiskers.client.Buzz;
于 2013-08-16T03:41:39.630 回答