【问题标题】:Regex matching interpretation with whitespace/non-digit/word boundary带有空格/非数字/单词边界的正则表达式匹配解释
【发布时间】:2015-10-05 15:20:45
【问题描述】:

我们有以下代码

String str = "ABC 2015 ABC1";
Pattern pattern = Pattern.compile("\\b\\w+\\D\\b");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
  System.out.println(">" + matcher.group() + "<");
}

我们的假设是它应该匹配 ABC 和 2015 与周围的单词边界(不消耗字符),w+ 单词字符匹配子串本身,然后非数字 \D 匹配空白。 ABC1 不应该匹配,因为后面没有空格

结果打印输出

>ABC <
>2015 < 

似乎证实了这一点,但是稍微改变 str 开始引发对上述匹配解释是否正确的怀疑。例如

  • 将其修改为带有尾随空格的“ABC 2015 ABC1”似乎会产生完全相同的结果,但不匹配 >ABC1

  • 将其修改为“ABC”且没有尾随空格会产生 >ABC

  • 将其修改为带有尾随空格的“ABC”会再次产生 >ABC

如果有人能解释正确的解释,将不胜感激

【问题讨论】:

    标签: java regex string


    【解决方案1】:

    然后是空格的非数字 \D。

    但是空格和下一个字符之间没有单词边界。

    你的正则表达式必须是,

    "\\b\\w+(?=\\s)"
    

    【讨论】:

    • 谢谢,但问题是如何解释上述匹配,而不是如何修改它
    • 你的意思是"\\b\\w+(?=\\D)"
    【解决方案2】:

    我认为您的困惑源于误解\b - word-boundary。

    \b 是一个零长度 匹配,它将匹配单词\w+ 的任何开头或结尾。

    在我们的例子中,字符串"ABC 2015 ABC1" 显然由于\D 而不会匹配。

    通过添加空格,您可以为正则表达式的以下部分创建一个很好的匹配 \\b\\w+\\D --> "ABC1 " 但现在单词边界将不匹配,因为在空格之后没有任何开始/一个词的结尾。

    如果您将字符串修改为:"ABC 2015 ABC1 x",它将“修复”该问题,因为附加的新字符将提供匹配,因为它之前的(零长度)字边界。

    Avinash 写了一个正确的答案,也解释了这个问题 - 但你没有理解它(再次阅读他答案的前两行),我认为他的答案应该被接受(我 +1)。

    【讨论】:

    • 话虽如此,我仍然不明白为什么匹配组以空格结尾,例如>ABC
    • @hammerfest 确实,\D 代表任何非数字字符与空格匹配。 "ABC " 后面的词边界是由于它后面的“2015”:“2015”是另一个“词”,它之前的零长度边界与 \b 之后的 \\b\\w+\\D
    • 谢谢。但这不与 Avinash 在上面的回答“但空白和下一个字符之间不存在单词边界”相矛盾吗?您认为这是正确的?
    • @hammerfest 那“下一个字符”是什么?在""ABC 2015 ABC1 " 没有这样的字符的情况下,下一个标记是end-of-string,它被正则表达式标记为$。通过添加x,如上面提供的示例:"ABC 2015 ABC1 x"创建“下一个字符”,然后您将获得“ABC1”与\b\w+\D\b之间的匹配。
    • 抱歉回复晚了。我现在已经对这个问题进行了更详细的分析,我想现在已经很清楚了。解释上的大部分混淆实际上来自于您的哪些陈述与哪个示例字符串相关并不明显。根据您的建议,我将亲自投票给 Avinash 的回答,不过我也感谢您的帮助。
    猜你喜欢
    • 2014-05-24
    • 1970-01-01
    • 2022-07-06
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多