非回溯子表达式如何工作"(?> exp)"

Ton*_*Nam 8 .net c# regex

我正试图在正则表达式上变得更好.我很难理解什么(?> expression )意思.我在哪里可以找到有关非倒缝亚咖啡的更多信息?的描述链接说:

贪婪的子表达式,也称为非回溯子表达式.这只匹配一次,然后不参与回溯.

这个其他链接:http://msdn.microsoft.com/en-us/library/bs2twtah (v=vs.71) .aspx也有非回溯子表达式的定义,但我仍然很难理解它是什么意思是加上我想不出一个我将使用的例子(?>exp)

Tim*_*ker 10

与往常一样,regular-expressions.info是一个很好的起点.

如果要确保曾经匹配过的任何内容都将保持匹配的一部分,请使用原子组.

例如,为了匹配可能或可能不用空格分隔的多个"单词",然后是冒号,用户尝试使用正则表达式:

(?:[A-Za-z0-9_.&,-]+\s*)+:
Run Code Online (Sandbox Code Playgroud)

当有比赛时,一切都很好.但是当没有时,由于灾难性的回溯,他的PC将因100%的CPU负载而无响应,因为正则表达式引擎会徒劳地试图找到匹配的单词组合,这将允许后面的冒号匹配.这当然是不可能的.

通过使用原子组,可以防止这种情况:

(?>[A-Za-z0-9_.&,-]+\s*)+:
Run Code Online (Sandbox Code Playgroud)

现在匹配的任何东西都保持匹配 - 没有回溯,因此快速失败的时间.

我最近遇到的另一个好例子:

如果要匹配所有未跟随ASCII字母的数字,则可能需要使用正则表达式\d+(?![A-Za-z]).但是,这将123a因输入而失败,因为正则表达式引擎将12通过回溯来愉快地返回匹配,直到后面的字符不再是字母.如果你使用(?>\d+)(?![A-Za-z]),这不会发生.(当然,\d+(?![\dA-Za-z])也会有效)


Ken*_*rey 8

正则表达式教程在这里有一个页面:http://www.regular-expressions.info/atomic.html

基本上它所做的是丢弃回溯信息,意味着a(?>bc|b)c匹配abcc但不是abc.

它与第二个字符串不匹配的原因是因为它找到匹配bc,并丢弃有关bc|b交替的回溯信息.它基本上忘记了它的|b一部分.因此,c之后没有bc,并且匹配失败.

使用原子组的最有用方法是调用慢速正则表达式.您可以在上述页面中找到更多信息.