占有量词和一次性子模式之间的区别

时间:2013-08-17 18:50:18

标签: php regex pcre

我正在阅读PCRE文档,我注意到占有量词+和只有一次的子模式(?>),也称为原子组,在概念上有些相似。有什么实质性的区别吗?

3 个答案:

答案 0 :(得分:7)

(?>)实际上是原子分组。

来自Atomic Grouping on regular-expressions.info

  

原子组是一个组,当正则表达式引擎退出时,   自动抛弃任何人记住的所有后退位置   组内的令牌。原子组是非捕获的。语法   是(?>组)。

来自Possessive Quantifiers on regular-expressions.info

  

占有量词是防止正则表达式引擎的一种方法   尝试所有排列。这主要用于提高性能   原因。您还可以使用占有量词来消除某些   匹配。

从同一页面:

  

从技术上讲,占有量词是一种符号方便   将一个原子组放在一个量词周围。所有正则表达口味   支持占有量词也支持原子分组。但   并非所有支持原子分组支持的正则表达式都具有占有性   量词。有了这些口味,你可以达到完全相同的效果   使用原子组的结果。

     

基本上,不是X*+,而是写(?>X*)。重要的是要注意   量化的标记X和量词都在里面   原子团。即使X是一个群体,你仍然需要额外增加   它周围的原子团达到了同样的效果。 (?:a|b)*+是   相当于(?>(?:a|b)*),但不是(?>a|b)*。后者是有效的   正则表达式,但在使用时不会产生相同的效果   正则表达式的一部分。

答案 1 :(得分:1)

如果查看this page of regular-expressions.info,您会在表格中注意到“x++(?>x+)相同”。

唯一的区别是:

  

占有量词是原子分组的有限但语法上更清晰的替代方法。

因此,它不像原子分组那样受欢迎,但可以认为它更清晰。

答案 2 :(得分:1)

请注意,(?>X+)与回溯视点中的X++并不完全相同。因为在括号内,正则表达式引擎有可能回溯,因此正则表达式引擎记录了原子组内部的所有回溯位置(但是一旦括号关闭就会忘记它们),当然,它可能不是占有量词的情况。例如:

考虑字符串aaaabbbb

(?>a+)ab a++ab将失败,因为一旦原子组的括号关闭,正则表达式引擎无法回溯。

(?>a+ab)将成功,因为回溯位置始终记录在原子组内。

(?:a+|ab)+(?<!a)b会成功,但(?>a+|ab)+(?<!a)b会失败,因为在每次重复之间都会关闭括号。

结论:(?>X+)的确切同义词不是X++,而是(?:X+){1}+