原子组是否总是在内部使用交替|
?我得到了来自"所有回溯位置的印象,这些位置被团队中的任何代币记住了#34; from:
原子组是一个组,当正则表达式引擎退出时, 自动抛弃任何人记住的所有回溯位置 小组内的令牌。原子组是非捕获的。语法 是(?>组)。
一个例子将使原子组的行为变得清晰。经常 表达式a(bc | b)c(捕获组)匹配abcc和abc。正则表达式 a(?> bc | b)c(原子组)与abcc匹配但不与abc匹配。
你能给出一个例子,其中使用的原子组没有交替|
吗?感谢。
答案 0 :(得分: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>