java - 为什么正则表达式\w*(\s+|$) 找到 2 个匹配项 "foo"(Java)?

标签 java regex

给定正则表达式 \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/

相关文章:

java - Dspace XMLUI 配置

java - 为什么我会收到 ClassCastException

java - 例如,我如何区分 hello1 和 hello 11?

python - 在Python中为每个正则表达式匹配添加后缀?

java - 正则表达式解析一行中的两个数字

Java夏令时似乎是错误的

java - jLayer——播放 mp3 导致文件开头失真

Java:如何定义基于整数的自定义数据类型?

regex - 如何查找两个日期之间的小时数 dd/mm/yyyy hh :mm

c# - 使用正则表达式从字符串中删除标点符号和空格