一、什么是正则回溯
1.简述
常见的正则引擎,被细分为 DFA(确定性有限状态自动机)与 NFA(非确定性有限状态自动机)
DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
正则回溯是一种正则表达式NFA引擎使用的技术,用于尝试所有可能的匹配方式,直到找到匹配为止。在正则表达式的匹配过程中,如果当前部分无法匹配,引擎会回溯到前面的部分,尝试其他可能的匹配路径。这可能会导致性能下降,特别是在复杂的正则表达式和长字符串的情况下,所以PHP限制正则回溯次数为100w次,如果超过,正则将会失效。
2.示例
当前面分支/重复匹配成功后,没有多余的文本可被正则后半部分匹配时,会产生回溯
用一个简单的例子来解释一下贪婪匹配和惰性匹配!
贪婪 : /\d+\b/
惰性 : /d+?\b/
文本 : 1234a
贪婪正则匹配 1234a 时的过程是这样的:
1. \d+ 匹配得到 1234
2. \b 却匹配失败,因为它的左边必须是数字,而不是字母 (\b 是分词边界匹配,用来获取位置)
4. 这个时候,\d+会尝试回吐一个字符,即匹配结果为 123 ,可\b还是匹配失败!
5. 那就继续回吐,一直到 1,还是匹配失败,那么这个正则就整体匹配失败了
6. 这个回吐匹配结果的过程就是回溯
惰性正则匹配 1234a 时的过程是这样的:
1. \d+? 首先匹配,结果是 1 ,紧接着 \b 匹配失败
2. 那就 \d+? 继续匹配,结果是 12 ,紧接着 \b 还是匹配失败
3. \d+? 一直匹配到1234,紧接着的 \b 依然匹配失败
4. 结果整个正则匹配不成功
通过这两个例子的比较,相信你会猜到回溯会影响匹配速度,回溯的过程慢那是相对那些DFA引擎。而JS的正则引擎是NFA(非确定型有限自动机),匹配慢,编译快。
注:
贪婪匹配
属于贪婪模式的量词,也叫做匹配优先量词,包括:{m,n},{m,},?,* 和 + 。
惰性匹配
在匹配优先量词后加上?,即变成属于惰性匹配的量词,也叫做忽略优先量词,包括:{m,n}?,{m,}?,??,*? 和 +? 。
具体参考:
正则回溯与awk练习_Catherines7的博客-优快云博客
http://t.csdn.cn/xIAPw