正则表达式的回溯机制
来源:互联网 发布:52kkm软件下载 编辑:程序博客网 时间:2024/06/05 07:41
正则表达式的引擎分析
正则表达式的引擎有两个特点:
1.默认情况下都是贪婪匹配。
2.引擎总是着急的,会返回最先匹配到结果正则引擎的工作原理举例:
当把cat应用到“He captured a catfish for his cat”,引擎先比较c和“H”,结果失败了。于是引擎再比较c和“e”,也失败了。直到第四个字符,c匹配了“c”。a匹配了第五个字符。到第六个字符t没能匹配“p”,也失败了。引擎再继续从第五个字符重新检查匹配性。直到第十五个字符开始,cat匹配上了“catfish”中的“cat”,正则表达式引擎急切的返回第一个匹配的结果,而不会再继续查找是否有其他更好的匹配。
回溯机制
回溯原理的简单解释
前面的引擎分析,只是针对简单的正则匹配分析,但是我们都知道正则表达式中还有很多模糊的条件匹配。这时候引擎该如何处理呢?对于计算机而言,处理模糊匹配的最好办法就是穷举,把所有可能的结果都找一遍,别忘了引擎本身都是着急的,也就是说当他匹配到一种可能性之后就不会再匹配剩余的结果。其中这种根据可能性查找的机制就叫回溯。
举个例子:用正则表达式 <.+>匹配字符串“This is a <EM>first</EM> test”,在这里首先<.+会先匹配出 “<EM>first</EM> test”,但是当>匹配换行符的时候会失败,如果前面你没有用.+这类的模糊语义的话,字符串就会匹配失败,但是由于你用.+这种模糊语义,等于给予了计算机更多的可能性,于是计算机会从最近的可能找起,因此>就会按照可能的顺序去匹配“t”,
“s”,“e”···一直匹配到">",由于引擎是着急的,所以他马上就返回了匹配结果“<EM>first</EM>”。分支和回溯
下面的例子演示了这一过程是如何处理分支的。/h(ello|appy) hippo/.test("hellothere, happyhippo");
此正则表达式匹配“hellohippo”或“happyhippo”。测试一开始,它要查找一个h,目标字符串的第一个字母恰好就是h,它立刻就被找到了。接下来,子表达式(ello|appy)提供了两个处理选项。正则表达式选择最左边的选项(分支选择总是从左到右进行),检查ello是否匹配字符串的下一个字符。确实匹配,然后正则表达式又匹配了后面的空格。然而在这一点上它走进了死胡同,因为hippo 中的h 不能匹配字符串中的下一个字母t。此时正则表达式还不能放弃,因为它还没有尝试过所有的选择,随后它回溯到最后一个检查点(在它匹配了首字母h 之后的那个位置上)并尝试匹配第二个分支选项。但是没有成功,而且也没有更多的选项了,所以正则表达式认为从字符串的第一个字符开始匹配是不能成功的,因此它从第二个字符开始,重新进行查找。它没有找到h,所以就继续向后找,直到第14 个字母才找到,它匹配happy的那个h。然后它再次进入分支过程。这次ello未能匹配,但是回溯之后第二次分支过程中,它匹配了整个字符串“happyhippo”。匹配成功了。
重复与回溯
下一个例子显示了带重复量词的回溯。//测试用的字符串var str = "<p>Para </p>" +"<img src='smiley.jpg'>" +"<p>Para </p>" +"<div>Div.</div>";//正则表达式匹配测试/<p>.*<\/p>/i.test(str);
正则表达式一上来就匹配了字符串开始的
<p>
。然后是.*
。点号匹配除换行符以外的任意字符,星号这个贪婪量词表示重复零次或多次——匹配尽量多的次数。因为目标字符串中没有换行符,它将吞噬剩下的全部字符串!不过正则表达式模板中还有更多内容需要匹配,所以正则表达式尝试匹配<
。它在字符串末尾匹配不成功,所以它每次回溯一个字符,继续尝试匹配<
,直到它回到</div>
标签的<
位置。然后它尝试匹配\/(转义反斜杠)
,匹配成功,然后是p
,匹配不成功。正则表达式继续回溯,重复此过程,直到第二段末尾时它终于匹配了</p>
。匹配返回成功,它从第一段头部一直扫描到最后一个的末尾,这可能不是你想要的结果。注意事项
1.注意减少正则表达式的回溯次数,如果回溯过多,会导致回溯失控出现,即 当一个正则表达式占用浏览器上秒,上分钟或者更长时间。
2.尽可能的使用简单,明确的语义去编写,正则表达式。
3.其他优化事项见正则表达式优化诀窍
- 正则表达式的回溯机制
- 正则表达式的灾难性回溯
- 通配符、正则表达式的回溯解法
- 正则表达式回溯
- 正则表达式的回溯数和嵌套数
- 正则表达式 <4> 贪婪与非贪婪的回溯
- 正则表达式--子表达式及回溯引用
- 正则的回溯功能
- 第四章 正则表达式回溯法原理
- Javascript--正则表达式工作原理, 回溯
- Java - 反射机制 - 正则表达式
- Java的内存泄漏和垃圾回收机制 && 正则表达式
- JQuery easyUI扩展验证机制的正则表达式
- JQuery easyUI扩展验证机制的正则表达式
- JQuery easyUI扩展验证机制的正则表达式
- 中文地址 解析 正则表达式 回溯版 v1.0
- 黑马程序员-day4-正则表达式之回溯引用
- 正则表达式学习(十)回溯引用backreference
- Java基础2-----循环结构
- WinSokect 编程
- Android系统联系人信息获取
- 数值的整次方
- Spring简单入门
- 正则表达式的回溯机制
- Const、volatile、mutable的用法
- cookie与session使用介绍
- MaxPointsOnALine
- Blend Modes——混合模式
- 关于QSettings的用法
- 【计网】物理层详解
- [RK3288][Android6.0] 调试笔记 --- 开机设置默认出厂时间方法
- 屏幕适配