给定正则表达式 \w*(\s+|$)
和输入 "foo"
我希望 Java Matcher.find()
只为真一次:\w* 会消耗 foo,而 (\s+|$) 中的 $
应该消耗字符串的末尾。
我不明白为什么第二个 find() 也适用于空匹配。
示例代码:
public static void main(String[] args) {
Pattern p = Pattern.compile("\\w*(\\s+|$)");
Matcher m = p.matcher("foo");
while (m.find()) {
System.out.println("'" + m.group() + "'");
}
}
预期(由我)输出:
'foo'
实际输出:
'foo'
''
更新
我的正则表达式示例应该只是\w*$ 以简化产生完全相同行为的讨论。
所以事情似乎是如何处理零长度匹配。
我找到了 Matcher.hitEnd()
方法,它告诉您最后一个匹配项已到达输入的末尾,因此您知道不需要另一个 Matcher.find()
while (!m.hitEnd() && m.find()) {
System.out.println("'" + m.group() + "'");
}
!m.hitEnd()
需要在 m.find()
之前,以免错过最后一个字。
最佳答案
表达式 \\w*
匹配零个或多个字符,因为您使用的是 Kleene operator .
一个快速的解决方法是将表达式更改为 \\w+
编辑:
阅读 Matcher 的文档后,查找方法“从该匹配器区域的开头开始,或者,如果该方法的先前调用成功并且此后匹配器未被重置,则从上一个匹配项未匹配的第一个字符开始。”。在这种情况下,第一次调用时所有字符都匹配,因此第二次调用从空开始。
关于java - 为什么正则表达式\w*(\s+|$) 找到 2 个匹配项 "foo"(Java)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45092094/