这个正则表达式是怎么工作的?

4
System.out.println("du hast mich".replaceAll("(?<=^(.*)) ", ", $1 "));
// prints "du, du hast, du hast mich"

在look behind后面使用^符号的含义是什么?(我知道这个符号的标准含义是行首)为什么点符号可以匹配到du、du hast和du hast mich。简单来说,为什么点符号没有匹配整个字符串?

请给我一个解释,说明这个正则表达式如何正确地工作。我很好奇。感谢您的关注。


1
你究竟想要做什么? - anubhava
根据上下文,^ 可以表示“行的开头”或“非(表达式)”(但在这里,它表示行的开头)。 - Arnaud Denoyelle
3个回答

3

(?<= )向后查找的语法。 ^只是“字符串开头”的锚点。本质上,正则表达式的含义是:

“匹配一个空格,该空格位于字符串开头和任意数量的字符之前。空格之前的字符是第一个捕获组。”


1
@MelihAltıntaş 它只匹配到回顾结束的地方,这个地方刚好在空格之前(否则就不是回顾了)。而且每个空格都会单独匹配,所以你会得到多个匹配结果。 - Kendall Frey
谢谢您的关注 :) 我没有看到最后一个空格,但我一直在努力理解 :)) - Melih Altıntaş

2
肯达尔有解释。以下是逐步说明。
du hast mich
 ^ regex hasn't matched anything so no replacement

写入
du

下一步。
du hast mich
  ^ regex matches

将匹配项替换为逗号和空格之前的所有内容。
, du

下一步。
du hast mich
      ^ no match

写入

hast

下一步
du hast mich
       ^ regex matches

将匹配的内容替换为逗号和空格前面的所有内容。
, du hast

下一步
du hast mich
           ^ no match

保持不变

mich

将所有这些结合起来,你就得到了。
du, du hast, du hast mich

1
@MelihAltıntaş 请注意您的正则表达式中最后一个 ) 后面的空格。 - Sotirios Delimanolis
谢谢您的关注 :) 我没有看到最后一个空格,但我一直在努力理解 :)) - Melih Altıntaş

0

那个正则表达式根本不应该起作用。它应该抛出异常,因为回顾后发现有一个开放的量词(.*)。你似乎发现了一个可以绕过这个规则的漏洞。但是不要使用它!这绝对是一个错误,而不是一个特性。

Java的回顾后查找一直有点棘手,我认为这是由于其复杂的已知最大长度要求引起的。我开始觉得这个特性是一个错误;它并没有足够的用处来证明它带来的麻烦。这就是为什么我尽量避免在我的回顾后查找中使用任何量词。


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