可变大小的环视如何工作

时间:2012-11-15 05:42:12

标签: regex regex-lookarounds

当RegEx引擎到达RegEx中的多个环顾部分时,内部如何工作。

我已经阅读了这个excellent article,但它没有涵盖外观。任何人都可以通过类似的方法解释一下(负面,正面,后面,前进)机制吗?

(我也很想知道引擎如何解释正则表达式:( RegEx s是不同的正则表达式字符串,可能是可变大小的,包括+*)< / p>

RegEx (?<!RegEx)(?<=RegEx)(?!RegEx)(?=RegEX) RegEx (?<!RegEx)(?<=RegEx)(?!RegEx)(?=RegEx)  RegEx

,我不想知道与它们匹配的内容,但我想知道引擎如何与它们一起行动,它们只是示例。感谢

NFA(非确定性有限自动化)图或任何类似的图表对说明该主题非常有用。

请不要将我推荐给regular-expressions.info,我已经读过了!它只是使用了两个非常简单的例子,我想知道一般的引擎机制。

1 个答案:

答案 0 :(得分:1)

Lookahead很简单:当引擎遇到超前表达式时,它将保存当前位置并通常检查它是否匹配。如果不是,则返回失败(允许引擎检查正则表达式的早期部分的其他选项)。如果是,则恢复保存的位置并继续检查正则表达式的其余部分。

Lookbehind更加强硬。在Python中,对它们的限制是它们必须是固定大小的。这使得评估变得容易:当遇到它时,如果它们与表达式匹配,则检查先前的[宽度]字符,其余的像前瞻一样。如果不使用此固定大小限制,则评估会变慢。这并不意味着算法变得复杂:它可以简单地尝试当前位置之前的所有字符串(前面的0个字符,前面的1个字符,前面的2个字符等,直到匹配,或者到达字符串的开头)。

至于订单,默认情况下正则表达式是贪婪的。这意味着在.*(s?)这样的表达式中,(s?)永远不会匹配任何内容,因为如果有s,则它已经与.*匹配。如果您不想这样做,请在?*之后添加+

现在举例来说:

  • /.*a(?=.*)/匹配任何内容,包括最后a(贪婪)。 (?=.*)始终匹配,因此它毫无价值:如果省略则正则表达式相同。
  • /.*a(?!a*)/永远不会匹配任何内容:否定前瞻中的表达式始终匹配(如果仅作为“0次a”)。由于它是否定的,这意味着前瞻总是失败。
  • /.*a(?=[^a]*)(?=[x])(?![c]*)/永远不会匹配任何内容。引擎将首先尝试.*a以匹配包含最后a的内容。这从未跟随另一个a,因此第一个前瞻总是成功(仅第一次)。如果后面没有x,则下一个前瞻会失败(注意括号在那里没用; [x]x相同)。如果失败,它将为.*a尝试一个较短的字符串,直到(第一个和第二个)前瞻符合。请注意,第一个前瞻始终匹配第二个前瞻,因此它没有用。然而,第三个前瞻废话了一切:[c]*(与c*相同)总是匹配(在任何位置你可以说“这个空字符串是字符c的0倍的列表”),这意味着负面前瞻总是失败。

你可能会感兴趣的是,如果模式非贪婪会发生什么。例如,/.*?a/将匹配包含a的任何内容,包括字符串中的第一个(而不是最后一个)a