原子组是否总是与交替使用内?

时间:2014-06-07 14:59:42

标签: regex

原子组是否总是在内部使用交替|?我得到了来自"所有回溯位置的印象,这些位置被团队中的任何代币记住了#34; from

  

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

     

一个例子将使原子组的行为变得清晰。经常   表达式a(bc | b)c(捕获组)匹配abcc和abc。正则表达式   a(?> bc | b)c(原子组)与abcc匹配但不与abc匹配。

你能给出一个例子,其中使用的原子组没有交替|吗?感谢。

1 个答案:

答案 0 :(得分:3)

交替与原子组无关。原子团的要点是避免回溯。这有两个主要原因:

  1. 当正则表达式无法匹配时,避免不必要的回溯。
  2. 避免回溯到您不想找到匹配项的表达式的一部分
  3. 您要求提供原子分组的示例而不进行更改。

    让我们看看两种用途。

    :一种。避免在失败时回溯

    例如,考虑这两个字符串:

    name=Joe species=hamster food=carrot says:{I love carrots} 
    name=Joe species=hamster food=carrot says:{I love peas}
    

    我们想要找到一个格式正确的字符串(它有key=value个令牌)并且在令牌后面有carrots,可能在says部分。尝试这种方法的一种方法可能是:

    非原子版

    ^(?:\w+=\w+\s+)*.*carrots
    

    这将匹配第一个字符串而不是第二个字符串。我们很开心。或者......我们真的吗?不满意有两个原因。我们将看看B部分的第二个原因(原子团的第二个主要原因)。那么第一个原因是什么?

    好吧,当您在RegexBuddy中调试失败案例时,您会发现在引擎决定它与第二个字符串不匹配之前需要引擎401步骤。这很长,因为在匹配令牌并且未能匹配carrots中的says:{I love peas}后,引擎会回溯到(\w+=\w+\s+)*,希望在那里找到carrots。现在让我们看看原子版本。

    原子版

    ^(?>(?:\w+=\w+\s+)*).*carrots
    

    这里,原子组阻止引擎回溯到(?:\w+=\w+\s+)*。结果是在第二个字符串上,引擎以64个步骤失败。比401快很多!

    <强> B中。避免回溯到不希望匹配的字符串的一部分

    保持相同的正则表达式,让我们稍微修改字符串:

    name=Joe species=hamster food=carrots says:{I love carrots} 
    name=Joe species=hamster food=carrots says:{I love peas}
    

    我们的原子正则表达式仍然有效(它匹配第一个字符串但不匹配第二个字符串)。

    然而,非原子正则表达式现在匹配两个字符串!这是因为在carrots中找不到says:{I love peas}后,引擎会回溯到令牌,并在carrots中找到food=carrots

    因此,在这种情况下,原子组是一个方便的工具,可以跳过我们不想找到carrots的字符串部分,同时仍然确保它的格式正确。< / p>