正则表达式匹配html打开和关闭标签(需要一些解释)

时间:2015-11-10 09:54:04

标签: regex

我很难理解正则表达式中的一些细微差别。我正在关注教程http://www.regular-expressions.info/backref.html并坚持使用backreferences匹配打开和关闭代码的示例。

我们有字符串:

Testing <B><I>bold italic</I></B> text

和表达:

<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>

我可以理解整个逻辑,但无法理解为什么引擎回溯到点:

  

现在引擎已经到达正则表达式中的第二个<了   字符串中的第二个<。这些匹配。下一个标记是/。这样做   不匹配I,引擎被迫回溯到点。点   匹配字符串中的第二个<。这个明星还是很懒,所以   引擎再次注意到可用的回溯位置和   进展到<I。这些不匹配,所以发动机再次   回溯。

为什么它回溯到点?这是因为我们已成功匹配前一部分的正则表达式,它总是回溯到上一次成功匹配的位置+ 1?

第二部分我无法完全理解。如果我们有一个字符串:

Testing <BOO><I>bold italic</I></B> text

和没有字边界的表达式:

<([A-Z][A-Z0-9]*)[^>]*>.*?</\1>
  

...在\1失败的地方查看正则表达式引擎   第一次。首先,.*?继续扩展,直到达到。{1}}   字符串的结尾,</\1>每次.*?匹配时都无法匹配   还有一个角色。

     

然后正则表达式引擎回溯到捕获组。 [A-Z0-9]*已与oo匹配,但与o或其他任何内容完全匹配。回溯时,[A-Z0-9]*被迫放弃一个角色。

为什么它会回溯到捕获组而不是像前面的示例那样点?我不明白为什么[A-Z0-9]*被迫放弃一个角色?是否存在引擎会回溯的一般规则?

1 个答案:

答案 0 :(得分:1)

注意 :它不是关于HTML解析,而是使用来自http://regular-expression.info/backref.html的HTML字符串示例深入了解回溯的工作原理

  

问题在于我无法理解为什么回溯回滚到特定位置是一般的。

关键是正则表达式引擎试图通过各种方式找到匹配。如果有选项,它可以根据当前模式遵循不同的路径,一旦它找到不匹配的符号,它将尝试它们。见backtracking introduction at rexegg.com

  

回溯是现代正则表达式引擎的一个很好的功能:如果一个令牌无法匹配,引擎会回溯到可能采用不同路径的任何位置。然后,贪婪量词可以放弃一个字符,懒惰量词可以扩展以匹配一个,或者可以尝试交替的最右侧。 如果模式继续失败,引擎会系统地探索所有可用路径。

因此,回溯可以回滚到具有量词/变换集的每个构造或分组,以确保在声明匹配失败之前尝试所有可能的组合。您始终回溯到最后匹配的符号的假设是不正确的。

回溯无法访问的唯一地方是原子组或拥有所有权量词的组。此外,环视为零长度的事实会自动使其成为原子(请参阅lookarounds)。

在第一个正则表达式中,\b标记一个单词边界,因此没有回溯到捕获组中,因为除了已经匹配之外没有其他单词边界。当您删除它时,回溯可以测试捕获组内的所有前面的位置。

要了解回溯和\b的重要性,请将这些正则表达式与Testing <Boo><I>bold italic</I></Bo> text输入进行比较: