注意: - 问题有点长,因为它包含了书中的部分。
我正在阅读Mastering Regular Expression中的atomic groups
。
atomic groups
导致更快失败。引用书中的特定部分
原子分组更快失败。考虑应用
^\w+:
Subject
。我们只能通过观察它才会看到它会失败 因为文本中没有冒号,而是正则表达式引擎 在它真正经历之前不会得出那个结论 检查的动议。因此,在首次检查
:
时,\w+
将走到字符串的末尾。这导致了很多 状态 -skip me
的每个匹配的一个\w
状态 (除了第一个,因为加号需要一个匹配)。然后检查 在字符串的末尾,:
失败,因此正则表达式引擎回溯到 最近保存的状态:在
:
再次失败,这次尝试匹配t
。这个 回溯测试失败循环一直发生在最旧的状态:从最终状态尝试后 失败,最终可以宣布整体失败。 所有这些回溯都是很多工作,只需一瞥就可以了 知道没必要。如果冒号在最后一次后无法匹配 字母,它当然不能匹配
+
被强制的一个字母 放弃!所以,知道
\w+
没有留下任何一个州,一次 它完成了,可能导致匹配,我们可以保存正则表达式 检查它们的麻烦:^(?>\w+):
。通过添加原子 分组,我们利用我们对正则表达式的全球知识来增强\w+
的本地工作是通过保存状态(我们知道的) 扔掉了。如果匹配,则原子分组不会 有重要的,但如果没有匹配,扔掉了 无用的状态让正则表达式得出更多结论 快。
我尝试了这些正则表达式 here 。 ^\w+:
需要4个步骤,^(?>\w+):
需要6个步骤(禁用内部引擎优化)
我的问题
因此,在首次检查
:
时,\w+
将前进到字符串的末尾。这导致很多状态 - 一个跳过我的状态为\w
的每个匹配加(除了第一个,因为加号需要一个匹配)。然后检查 在字符串的末尾,:
失败,因此正则表达式引擎回溯到 最近保存的状态:在
:
再次失败,这次尝试匹配t
。这个 回溯测试失败循环一直发生在最旧的状态:
但在 this 网站上,我看不到回溯。为什么?
内部是否有一些优化(即使在禁用之后)?
答案 0 :(得分:3)
该网站上的调试器似乎掩盖了回溯的细节。 RegexBuddy做得更好。这是^\w+:
在\w+
消耗所有字母后,它会尝试匹配:
并失败。然后它返回一个字符,再次尝试:
,然后再次失败。等等,直到没有什么可以回馈的。总共十五步。现在看一下原子版本(^(?>\w+):
):
第一次未能匹配:
后,它会立即返回所有字母,就好像它们是一个字符一样。共有五个步骤,其中两个进入和离开该组。使用占有量词(^\w++:
)甚至可以消除这些:
至于你的第二个问题,是的,来自正则表达式调试器的步数指标是有用的,特别是如果你只是学习正则表达式。每个正则表达式都至少有一些优化,即使是写得很糟糕的正则表达式也能充分发挥作用,但调试器(特别是像RegexBuddy这样的味道中立的版本)会让你在做错事时显而易见。 / p>