通过原子分组实现更快的失败意味着什么

时间:2016-05-16 10:32:38

标签: regex pcre

注意: - 问题有点长,因为它包含了书中的部分。

我正在阅读Mastering Regular Expression中的atomic groups

atomic groups导致更快失败。引用书中的特定部分

  
    

原子分组更快失败。考虑应用^\w+:     Subject。我们只能通过观察它才会看到它会失败     因为文本中没有冒号,而是正则表达式引擎     在它真正经历之前不会得出那个结论     检查的动议。

         

因此,在首次检查:时,\w+     将走到字符串的末尾。这导致了很多     状态 - skip me的每个匹配的一个\w状态     (除了第一个,因为加号需要一个匹配)。然后检查     在字符串的末尾,:失败,因此正则表达式引擎回溯到     最近保存的状态:

  
     

enter image description here

     
    

在     :再次失败,这次尝试匹配t。这个     回溯测试失败循环一直发生在最旧的状态:

  
     

enter image description here

     
    

从最终状态尝试后     失败,最终可以宣布整体失败。     所有这些回溯都是很多工作,只需一瞥就可以了     知道没必要。如果冒号在最后一次后无法匹配     字母,它当然不能匹配+被强制的一个字母     放弃!

         

所以,知道\w+没有留下任何一个州,一次     它完成了,可能导致匹配,我们可以保存正则表达式     检查它们的麻烦:^(?>\w+):。通过添加原子     分组,我们利用我们对正则表达式的全球知识来增强     \w+的本地工作是通过保存状态(我们知道的)     扔掉了。如果匹配,则原子分组不会     有重要的,但如果没有匹配,扔掉了     无用的状态让正则表达式得出更多结论     快。

  

我尝试了这些正则表达式 here ^\w+:需要4个步骤,^(?>\w+): 需要6个步骤(禁用内部引擎优化)

我的问题

  1. 在上一节的第二段中,提到
  2.   
        

    因此,在首次检查:时,\w+将前进到字符串的末尾。这导致很多状态 - 一个跳过我的状态为\w的每个匹配加(除了第一个,因为加号需要一个匹配)。然后检查     在字符串的末尾,:失败,因此正则表达式引擎回溯到     最近保存的状态:

      
         

    enter image description here

         
        

    在     :再次失败,这次尝试匹配t。这个     回溯测试失败循环一直发生在最旧的状态:

      
         

    enter image description here

    但在 this 网站上,我看不到回溯。为什么?

    内部是否有一些优化(即使在禁用之后)?

    1. 正则表达式采取的步骤数决定一个正则表达式是否比其他正则表达式具有良好的性能?

1 个答案:

答案 0 :(得分:3)

该网站上的调试器似乎掩盖了回溯的细节。 RegexBuddy做得更好。这是^\w+:

的内容

Normal (greedy)

\w+消耗所有字母后,它会尝试匹配:并失败。然后它返回一个字符,再次尝试:,然后再次失败。等等,直到没有什么可以回馈的。总共十五步。现在看一下原子版本(^(?>\w+):):

Atomic

第一次未能匹配:后,它会立即返回所有字母,就好像它们是一个字符一样。共有五个步骤,其中两个进入和离开该组。使用占有量词(^\w++:)甚至可以消除这些:

Possessive

至于你的第二个问题,是的,来自正则表达式调试器的步数指标是有用的,特别是如果你只是学习正则表达式。每个正则表达式都至少有一些优化,即使是写得很糟糕的正则表达式也能充分发挥作用,但调试器(特别是像RegexBuddy这样的味道中立的版本)会让你在做错事时显而易见。 / p>