不同的量词如何使正则表达式表现得不同?

时间:2017-06-02 10:41:02

标签: regex

a question asked earlier(搁置,但我想摆弄它;)我偶然发现了一个特殊性,我想问这个知识渊博的社区。即 - 为什么这两个正则表达式会产生不同的结果

(\b\w+(?:\s+\w+)+)(?:.*?(\1))(?:.*?(\1))?(?:.*?(\1))?

VS

(\b\w+(?:\s+\w+)+)(?:.*?(\1)){1,3}

First at regex101 - Second at regex101

我想做的是拥有这个正则表达式:

(\b\w+(?:\s+\w+)+)(?:.*?(\1))+

检测重复的单词序列 - regex101。 (一个单词后面跟着至少一个。然后重复所识别的序列,然后这个最后一部分可能重复任意次。即一次或多次重复。)

它所做的是找到一个序列,在文档中稍后重复它,但它跳到最后一个。好吧,虽然我认为我对正则表达式感到有些自在,但我知道贪婪与懒惰相比可能令人困惑。我想让它抓住所有重复。

所以我试图通过重复第二部分而不是使用量词强制它:

(\b\w+(?:\s+\w+)+)(?:.*?(\1))(?:.*?(\1))

然后它按预期工作 - regex101

这让我尝试了首次提到的两个正则表达式,在我看来应该产生相同的结果,但它们没有。那么,再次 - 是什么让他们给出不同的结果?

2 个答案:

答案 0 :(得分:1)

当你重复一个捕获组时,只有最后一个"捕获"被放在后面的参考文献中。

例如/A(B)+/用于字符串" ABBB"会把最后一个" B"在捕获组$ 1。

但是/A(B)(B)(B)/有3个捕获组,因此会有一个" B" 1美元和1美元$ 2& $ 3'/ P>

这就是为什么在你展示的2个正则表达式示例中,第一个也将标记为第2个"我的猫是黑色"。
但是第二个正则表达式的例子不然。

答案 1 :(得分:1)

您的原始模式(\b\w+(?:\s+\w+)+)(?:.*?(\1))+将跳到上一个重复的子模式,因为您告诉它使用最后一个+执行此操作 - 您量化捕获组,这意味着当(?:.*?(\1))+首次点击“我的猫是黑色的”时 它会一直重复,直到找到最长的匹配为止捕获组的所有中间匹配都将被丢弃。

一般来说,不要量化捕获组,捕获量化组。

我认为你想要的只是这个:

(\b\w+(?:\s+\w+)+).*?(\1)

https://regex101.com/r/OzDdCs/7