1、前言:
最近在看性能调优,说到合理使用正则表达式或者能不用就不用,有点好奇,就去了解了下,这里简单记录下了解到的内容。
2、实现正则表达式引擎的方式:
目前实现正则表达式引擎的方式有两种:DFA 自动机(Deterministic Final Automaton 确定有限状态自动机)和 NFA 自动机(Non deterministic Finite Automaton 非确定有限状态自动机)。
目前绝大多数都是使用了NFA,这两者要详细了解下可以看看这(有穷自动机DFA&NFA (学习笔记) - 知乎)
3、匹配模式:
合理使用匹配模式能减少不必要的回溯,但是有些回溯是必须的,并不能避免。比较详细:一个由正则表达式引发的血案 - 明志健致远 - 博客园
3.1、贪婪模式
顾名思义,就是在数量匹配中,如果单独使用 +、 ? 、* 或{min,max} 等量词,正则表达式会匹配尽可能多的内容。例如,
text="abbc"
regex="ab{1,3}c"
就是在贪婪模式下,NFA 自动机读取了最大的匹配范围,即匹配 3 个 b 字符。匹配发生了一次失败,就引起了一次回溯。
3.2、懒惰模式(Reluctant)
在该模式下,正则表达式会尽可能少地重复匹配字符。如果匹配成功,它会继续匹配剩余的字符串。例如,在上面例子的字符后面加一个“?”,就可以开启懒惰模式。
text="abbc"
regex="ab{1,3}?c"
匹配结果是“abc”,该模式下 NFA 自动机首先选择最小的匹配范围,即匹配 1 个 b 字符,因此就避免了回溯问题。
3.3、独占模式(Possessive)
还是上边的例子,在字符后面加一个“+”,就可以开启独占模式。例如,
text="abbc"
regex="ab{1,3}+bc"
结果是不匹配,结束匹配,不会发生回溯问题。