我正在努力变得更擅长正则表达式。我很难理解 (?> expression )
是什么意思。我在哪里可以找到更多关于非回溯性 subexpressoins 的信息? THIS的说明链接说:
Greedy subexpression, also known as a non-backtracking subexpression. This is matched only once and then does not participate in backtracking.
此其他链接:http://msdn.microsoft.com/en-us/library/bs2twtah(v=vs.71).aspx也有非回溯子表达式的定义 ,但我仍然很难理解它的含义,而且我想不出一个我将使用 (?>exp)
最佳答案
一如既往,regular-expressions.info是一个很好的起点。
如果您想确保曾经匹配的任何内容都将保留在匹配中,请使用原子组。
例如,为了匹配一些可以用空格分隔,也可以不用空格分隔,然后后跟冒号的“单词”,用户尝试了正则表达式:
(?:[A-Za-z0-9_.&,-]+\s*)+:
有比赛的时候,一切都很好。但如果没有,他的 PC 会因为灾难性的回溯而在 100% 的 CPU 负载下变得无响应,因为正则表达式引擎会徒劳地尝试找到允许以下冒号匹配的匹配单词组合。这当然是不可能的。
通过使用原子组,可以避免这种情况:
(?>[A-Za-z0-9_.&,-]+\s*)+:
现在任何已匹配的都保持匹配 - 没有回溯,因此失败时间很快。
我最近遇到的另一个很好的例子:
如果您想匹配所有后面没有跟 ASCII 字母的数字,您可能需要使用正则表达式 \d+(?![A-Za-z])
。但是,对于像 123a
这样的输入,这将失败,因为正则表达式引擎将很乐意通过回溯返回匹配 12
,直到后面的字符不再是字母。如果您使用 (?>\d+)(?![A-Za-z])
,则不会发生这种情况。 (当然,\d+(?![\dA-Za-z])
也可以)
关于c# - 非回溯子表达式如何工作 "(?>exp)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11632247/