10

我似乎无法弄清楚?>正则表达式中的用途。例如,以下内容:

(?>[^()]+)

我知道这?:意味着如果您不打算反向引用匹配,它不应该存储匹配。这有什么关系吗?

这也与正则表达式有关吗?(?P>name)或者(?&name)

来源: http: //php.net/manual/en/regexp.reference.recursive.php

4

1 回答 1

10

(?>pattern)防止在pattern. 它至少有 2 个名称:非回溯组原子组。我将其称为非回溯组,因为它是最具描述性的名称。

不过,单独的表达式(?>[^()]+)不需要非回溯。没有什么可以诱导回溯以显示非回溯行为。

一个更有趣的例子是正则表达式^\((?>[^()]+)\),匹配字符串(a + b(),与没有非回溯组的普通版本进行比较^\([^()]+\)

正常版本,在尝试(a + b匹配^\([^()]+文字并失败后,)将回溯一个字符并使用(a +等重试,直到(a,在用尽所有可能性后失败。

非回溯版本将在第一次尝试后立即失败(a + b

非回溯组主要用于减少由量词(?, *, +, {n,}, {n,m})引起的回溯。使用非回溯组进行优化的技巧是了解正则表达式引擎的第一次尝试。您可能需要移动正则表达式以确保引擎进行的第一次尝试是您想要匹配的 - 然后可以使其不回溯。

作为使用非回溯组进行优化的示例:

  • 如何提高 .NET 正则表达式的性能?

    我引用的问题来自.NET,但它对非回溯组使用相同的语法。

    在上面的问题中,原始的正则表达式有很多用法*+量词。当匹配失败时,它会导致不必要的回溯,从而影响大输入的性能。

  • 使用 RegEx 匹配大输入时出现 StackOverflowError

    另一个例子。注意所有格量词(+在普通量词之后添加,例如,,,?+等)和非回溯组具有非回溯的相同行为,只是非回溯组的语法允许它被推广。++*+

    在 PHP 中不会像在 Java 中那样出现堆栈溢出,但在验证长字符串时性能应该会更好。

于 2013-03-14T15:47:53.443 回答