教程 > 正则表达式 > 阅读:68

无限递归——迹忆客-ag捕鱼王app官网

无限递归


正则表达式,例如(?r)?za?(?r)?za|(?r)z在进入递归前没有任何的匹配,这种情况会导致无限递归。如果正则表达式引擎在不推进文本的情况下到达了递归,则下一个递归将在不推进文本的情况下再次到达递归。对于第一个正则表达式,这种情况会在匹配开始时立即发生。对于剩下的其他两个,当没有字母a匹配的时候,无限递归就开始产生了。

jgsoft v2和boost 1.64将前两个正则表达式视为语法错误,因为它们总是导致无限递归。他们允许第三个正则表达式,因为它能匹配字符a。ruby 1.9和更高版本,pcre的所有版本以及pcre2 10.20和先前版本将造成无限递归的所有三种形式都视为语法错误。perl,pcre2 10.21和更高版本以及boost 1.63和先前版本允许所有这三种形式。

循环无限子例程调用


子例程调用也可能导致无限递归。所有正则表达式引擎都以相同的方式处理((?1)?z)(a?(?1)?z)(a|(?1)z)中的潜在无限递归。

但是,如果子例程调用的组具有另一个子例程调用,而该子例程调用了第一个子例程调用的父组,则这些子例程调用本身并不具有递归性。当子例程调用被迫循环时,这也会导致无限递归。编译正则表达式时,检测此类循环调用比检查直接无限递归要复杂得多。只有jgsoft v2和ruby 1.9及更高版本才能检测到此错误并将其视为语法错误。所有其他引擎都允许使用这些正则表达式。

错误和崩溃


当发生无限递归时,无论是直接递归还是循环中的子例程调用,jgsoft v2,perl和pcre2都会将其视为匹配错误,从而中止整个匹配尝试。boost 1.64通过不尝试递归并假定递归失败来处理此问题。如果递归是可选的,则boost 1.64可能会在其他引擎抛出错误的地方找到匹配项。

当发生无限递归时,boost1.63和更早版本以及pcre 8.12和更早版本都会发生崩溃。由于它们基于较旧的pcre版本,这也会影响delphi最高版本xe6和php版本5.4.8。

无休止的递归


正则表达式如a(?r)z将导致无穷递归。因为正则表达式中的递归不是可选的,并且不具有选择项。这样的正则表达式永远找不到匹配项。当a匹配时,正则表达式引擎将尝试递归。如果可以匹配另一个a,则必须再次尝试递归。最终,a将用尽所有字母以进行匹配。递归然后失败。因为它不是可选的,所以正则表达式无法匹配。

jgsoft v2和ruby在编译正则表达式时会检测到这种情况。他们将无穷递归标记为语法错误。perl,pcre,pcre2和boost无法检测到无穷递归。他们只是简单地进行了匹配,并且宣告没有找到匹配项。

查看笔记

扫码一下
查看教程更方便
网站地图