正确理解正则表达式回溯在编写高质量js中的作用

正确理解正则表达式回溯在编写高质量js中的作用
当正则表达式扫描目标字符串,我们扫描正则表达式的组件从左到右,我们可以在每一个位置找到匹配。每个量词和分支,它必须决定如何继续。如果它是一个分类器(例如,* +或{ 2 })正则表达式必须被确定的时候,然后尝试匹配多个字符;如果分公司(由|算子),然后正则表达式必须选择尝试这些选项。

当正则表达式做出这样的决定,它会记住另一个选择,如果必要的话,在它返回使用。如果所选的项目匹配成功,正则表达式将继续扫描正则表达式模板,如果剩下的比赛是成功的,比赛将结束。然而,如果选定的方案未能找到相应的匹配或后续比赛失败,正则表达式将追溯到最后的决策点,然后选择剩下的选项。继续这样做,直到你找到一个匹配,或分类器和分支选项,所有可能的组合不放弃尝试失败后的处理,然后移动到下一个字符的开始重复这个过程,重复这个过程。

例如,下面的代码演示了如何通过回溯将这个过程分支。
/ H(i |阿皮)河马 /。试验(你好,快乐的河马);
上面的线正则表达式用于匹配河马或快乐河马。目标字符串的第一个字母是H,并立即找到。下一步,该子表达式(ELLO |阿皮)提供两处理选项。正则表达式选择最左边的选项(分支的选择总是从左到右行),检查ello是否匹配的字符串的下一个字符不匹配,和然后正则表达式匹配下面的空间。

然而,在接下来的比赛中,正则表达式走进死胡同,因为河马H不匹配一个字母T中的字符串,正则表达式不能被抛弃,因为它没有试过所有的选项之前,然后回到上一个检查点(匹配字母h),并尝试匹配二分支选项。但因为匹配不成功,没有更多的选择,正则表达式认为匹配从字符串的第一个字符是不成功的,所以它又开始从第二个字符。正则表达式没有找到,继续找落后,直到第十四封信被发现,这场幸福的H。随后,正规的E一进入分支过程。这一次的再见不匹配。但在第二个分支回溯后,它匹配了整串快乐的河马,比赛成功了。

同样,下面的代码演示了一个重复量词的回溯。
var str =准1。+++准2。+分;
/ / * i.test(STR);
正则表达式匹配的前3个字母的字符串,然后开始。点匹配除了换行字符,星号的贪婪量词重复匹配零次或更多次,尽可能多的时间。因为目标字符串中没有换行符,正则表达式将匹配所有剩下的字符串!但是,由于正则表达式模板的内容需要匹配,正则表达式尝试匹配标签。匹配返回成功需要从第一节到最后一段结束扫描,这可能不是我们想要的结果。

正则表达式中的贪心量词被转化为一个懒惰的(不贪心的)量词来匹配一个段落。*首先尝试跳过所有,然后继续匹配。

这样做是因为*匹配零次或多次,尽可能少地重复,尽可能少地重复0。

如果目标字符串只有一个段落,正则表达式的贪婪版本相当于懒惰版本,但试图匹配的过程是不同的。

当正则表达式以浏览器为几秒甚至更长的时间,这些问题可能是一个回溯失控。为了说明这个问题,下面的正则表达式,以匹配整个HTML文件。这个表达式分成多行来适应页面显示。不像其他的正则表达式,使用点匹配任何字符在选项的情况下,包括换行,所以在这种情况下,匹配任何字符{ }。
{
此正则表达式的作品时,它与一个普通的HTML字符串,但它变得更糟,当目标字符串缺少一个或多个标签,标签丢失,和最后的{ } *将扩展到字符串的末尾,因为没有标签找到,然后正则表达式会看回溯位置上{ 的 }×队列记录,并扩大它们进一步。正则表达式企图扩大二{ } *倒计时--匹配标签,即标签已经匹配正则表达式模板,然后搜索第二标签直到字符串结束。当所有这些步骤失败,第三{ 的 } *互惠将延长至年底的字符串,等等。

该问题的解决方案尽可能具体化字符、窗体(如模板)之间的分隔符。要匹配一个字符串的双引号,更具体的 RN } { ^ * *代替过于宽泛的消除了可能出现的问题,当试图使用回溯法,如点,引号,或扩展搜索范围超出预期。

在HTML的情况下,并不是如此简单。不能用消极的性格类型,如{ ^ < }而不是{ },因为搜索过程中可能遇到的其他类型的标签。然而,它可以通过重复非捕获组达到相同的结果,这包含一个回溯(阻断了所需要的下一个标签)和{ 的 }(任意字符)元素序列。这保证了在中间的每个标签查找失败。然后,更重要的是,该{ 的 }模板挡在回溯过程不能在发现延长。应用这种方法后,正则表达式的最终修改如下:
((())){ })*(()){ })*

((:){ })*(()){ })*

((:){ })*(()){ })*
(()){ { } })。
虽然这种方式消除潜在的回溯失控并允许正则表达式匹配的文本长度的线性时不完整的HTML字符串失败,正则表达式的效率并没有提高。这样,每一个匹配的字符是看了许多次,缺乏效率和匹配成功的过程是相当缓慢的。使用这种方法时匹配一个短的字符串,这是非常好的,和匹配一个HTML文件可能需要向前看,次测试数千。

tag:正则表达式作用回溯高质量正确理解

相关内容