正则表达式中的"独立非捕获组"是什么?

70

来自Java 6Pattern文档:

特殊结构(非捕获)

(?:X)   作为非捕获组的X

(?>X)   作为独立的、非捕获的组的X

(?:X)(?>X)之间有什么区别?在这个上下文中,“独立”是什么意思?

4个回答

51

这意味着分组是原子的,它会丢弃匹配组的回溯信息。因此,这个表达式是占有性的;即使这样做是整个正则表达式成功的唯一方式,它也不会后退。在这个意义上,它是“独立的”,因为它不通过回溯与正则表达式的其他元素合作以确保匹配。


14
我认为这篇教程解释了“独立的、不捕获分组”或“原子分组”的确切含义。
正则表达式a(bc|b)c(捕获分组)匹配abccabc。正则表达式a(?>bc|b)c(原子分组)匹配abcc但不匹配abc
当应用于abc时,两个正则表达式都将将aa匹配,将bcbc匹配,然后在字符串末尾失败地尝试将c与字符匹配。它们的路径在这里分叉。使用捕获分组的正则表达式记住了一个备用位置来进行选择。该组将放弃匹配,b然后匹配bc匹配c。找到匹配项!
然而,使用原子分组的正则表达式在匹配bc后退出了原子分组。此时,组内标记的所有备用位置都将被丢弃。在这个例子中,备选项在字符串的第二个位置尝试b的选择将被丢弃。结果,当c失败时,正则表达式引擎没有其他可尝试的方案。

6
如果您有foo(?>(co)*)co,那么它永远不会匹配。我相信有实际的例子可以说明这个正则表达式的用途,请参考O'Reilly的书籍。

-3

(?>X?) 等同于 (?:X)?+(?>X*) 等同于 (?:X)*+(?>X+) 等同于 (?:X)++

除了 X 必须是一个非捕获组之外,前面的等式可以简化为:

(?>X?) 等同于 X?+(?>X*) 等同于 X*+(?>X+) 等同于 X++


Pattern JavaDocs 中的 independent 一词非常重要。它们并不完全相同,因为 (?>X) 在部分匹配失败时不会进行任何回溯,所以使用其中一个匹配的某些内容将无法使用另一个匹配。 erickson 链接的文章对我很有帮助。 - xdhmoore
抱歉,我目前不太了解这个问题,所以我的答案可能不准确。但是根据您提供的参考资料:“大多数工具也支持占有量词,这实际上是原子组合的一种符号便利性。” 这就是我想表达的意思。在后一种情况下,额外的“+”字符表示占有限定符。 - beibichunai
我不喜欢这个答案,因为它只在X本身是原子时才有效,而在文档中并不一定是这种情况——有时候X必须是一个原子(例如X?+),有时候则不是(例如(X))。具体来说,(?>X?)仅当X是原子时等于X?+(?>foo?)不等同于(?:foo)?+ - Jelaby
Jelaby,在文档中你在哪里读到X必须是X原子?你能给出一个例子,其中X不是X原子吗? - beibichunai
我看到负面投票没有得到回答,这是意料之中的。?+ 可以应用于任何东西,包括原子或非原子,只要它是一个表达式。(?> )也是一样。如果 X 不是一个表达式,你就不会应用规则:AB?+ 等同于 A(?>B) 而不是 (?>AB?) - 仅适用于 B - 并且不能在 (?>AB?) 上反向应用,因为 AB 在那里不是一个表达式 - B 是,但 (> ) 不直接应用于结果 - B? - 而是应用于另一个表达式 AB?。显然,你必须知道优先级才能应用规则。问题不在于原子性,而在于无论表达式结构如何都使用规则。 - beibichunai
显示剩余2条评论

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