正则表达式原子团是分配的吗?

时间:2012-05-30 20:04:09

标签: regex

正则表达式原子组是分配的吗?

即。 (?>A?B?)始终等同于(?>A?)(?>B?)

如果没有,请提供一个反例。

2 个答案:

答案 0 :(得分:2)

一般的原子组

  1. 原子组(?>regex1|regex2|regex3)仅获取其中的第一个成功匹配。换句话说,它不允许回溯。

  2. 正则表达式从左到右进行评估,因此您表达了您想要匹配的顺序。发动机从第一个位置开始,试图成功匹配,必要时回溯。如果通过表达式的任何路径将导致成功匹配,那么它将在该位置匹配。

  3. 原子团不是分配的。考虑在ABC上评估的这些模式: (?>(AB?))(?>(BC))(不匹配)和(?>(AB?)(BC))(匹配ABC)。

  4. 包含所有可选组件的原子组

    但是,两个部分都是可选的情况可能不同。

    考虑具有2个贪婪的可选部分A和B((A)?(B)?)的原子组。在任何位置,如果A匹配,它可以继续评估可选的B。否则,如果A不匹配,那也没关系,因为它是可选的。因此,(A)?匹配任何位置。相同的逻辑适用于可选的B。剩下的问题是回溯是否会有任何差异。

    对于所有可选部分((?>A?B?)),由于每个部分始终匹配,因此没有理由在原子组内回溯,因此它将始终匹配。然后,由于它处于原子组中,因此禁止回溯。

    对于单独的原子组((?>A?)(?>B?)),每个部分始终匹配,并且在任何一种情况下都禁止引擎回溯。这意味着结果将是相同的。

    重申一下,引擎只能使用(?>A?)(?>B?)中的第一个匹配项,这与(?>A?B?)中第一个可能匹配的匹配项始终相同。因此,如果我的推理是正确的,对于特殊情况,匹配将是多个可选原子组的相同,作为具有两个可选组件的单个原子组。

答案 1 :(得分:1)

由于您没有指定,我假设您指的是Perl正则表达式,因为我没有看到任何其他语言的(?>)分组运算符。

请考虑以下事项:

ra = 'A?'
rb = 'B?'

/(?>${ra} ${rb})/x/(?>${ra})(?>${rb})/x相同。

在这种情况下,是的,它可以正常工作;但是,由于(?>)禁用了回溯功能,因此rarb的某些其他值并非如此。

例如,给定:

ra = 'A*'
rb = 'AB*'

/(?>${ra} ${rb})/x!= /(?>${ra})(?>${rb})/x

在后者中,rb永远不会匹配,因为ra将消耗整个A序列,并且不允许回溯。请注意,如果我们使用(?:)作为分组运算符,则工作。另请注意,如果我们使用了捕获组(),那么匹配将是相同的,但副作用(分配给\1\2,...)会有所不同。