Java正则表达式模式匹配在任何字符序列后第一次出现“边界”。

16

我想设置一个模式,该模式将查找由第一次出现的“边界”限定的捕获组。但现在使用了最后一个边界。

例如:

String text = "this should match from A to the first B and not 2nd B, got that?";
Pattern ptrn = Pattern.compile("\\b(A.*B)\\b");
Matcher mtchr = ptrn.matcher(text);
while(mtchr.find()) {
    String match = mtchr.group();
    System.out.println("Match = <" + match + ">");
}

打印:

"Match = <A to the first B and not 2nd B>"

我想让它打印出:

"Match = <A to the first B>"

在模式内需要改变什么?

4个回答

46

使用*?使你的*变成非贪婪模式 / 懒惰模式:

Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");

默认情况下,该模式会贪婪地匹配尽可能多的字符以满足模式,也就是说,直到最后一个 B

请参见文档中的"勉强量词"这个教程


6
不要使用贪婪表达式进行匹配,即:
Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");

4

*是贪婪量词,它尽可能匹配满足模式的多个字符。在你的例子中,它匹配到最后一个B出现的位置。这就是为什么你需要使用懒惰量词:*?,它会尽可能匹配少的字符。因此,你的模式应该稍作修改:

Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");

请参考文档中的“勉强量词”和本教程。 文档,和本教程

这是重新制作的 pb2q 答案,但未被接受。 - Timofey Gorshkov

1

也许比让 * 变得不情愿/懒惰更明确的是,你要寻找 A,然后是一堆不是 B 的东西,最后是 B:

Pattern ptrn = Pattern.compile("\\b(A[^B]*B)\\b");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接