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