正则表达式 - 嵌套的先行断言

时间:2014-05-29 08:20:37

标签: regex regex-lookarounds lookahead negative-lookahead

假设我们想要匹配此文本中one之间的所有<out>...</out>(选项:点匹配所有):

<out>hello!</out>
<nx1>home one</nx1>
<nx2>living</nx2>
<out>one text
text one continues 
and at last here ends one</out>
<m2>dog one</m2>
<out>bye!</out>

让我们说我们使用这种模式:

one(?=(?:(?!<out>).)*</out>)

如果有人解释了正则表达式引擎在每个处理阶段如何逐步处理该模式以及它将在何处(在原始文本中的位置),我真的很感激;(像接受@ Tim Pietzcker'这个问题的有用解释:Regex - lookahead assertion

2 个答案:

答案 0 :(得分:3)

Many tools的存在是为了自动解释你的正则表达式的作用。

背后的想法是,您要检查one后跟</out>,同时禁止输入新的out代码:如果有&#39; sa {{ 1}}跟随,我们还没有进入新的...</out>结构,我们知道我们已经进入了一个结构。

因此正则表达式将匹配<out>...</out>,如果后跟one,并且两者之间没有</out>

工作由<out>完成:(?:(?!<out>).)*只有在.中不是第一个<时才会匹配。因此,我们只能通过使用不是<out>后跟</out>的字符来升级<


速度提升将是:

out>

在每个角色的负向前瞻中踩踏大大增加了匹配此角色的成本。此处one(?=(?:[^<]*+|<(?!out>))*+</out>) 将直接与下一个可疑[^<]*+匹配,我们只在必要时执行否定预测检查。

答案 1 :(得分:1)

以下是here的解释:

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  one                      'one'
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the most amount
                             possible)):
--------------------------------------------------------------------------------
      (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
        <out>                    '<out>'
--------------------------------------------------------------------------------
      )                        end of look-ahead
--------------------------------------------------------------------------------
      .                        any character except \n
--------------------------------------------------------------------------------
    )*                       end of grouping
--------------------------------------------------------------------------------
    </out>                   '</out>'
--------------------------------------------------------------------------------
  )                        end of look-ahead