声明:本文整理自《精通正则表达式》
正则表达式匹配原理
匹配基础
- 优先选择最左端的匹配结果。
- 标准匹配量词
*
+
?
匹配优先。
回溯原则
如果需要在“进行尝试”和“跳过尝试”之间选择,对于匹配优先量词,引擎会优先选择“进行尝试”,对于忽略优先量词,会选择“跳过尝试”。
距离当前最近储存的选项就是当本地失败强制回溯时返回的。使用的原则是 LIFO 后进先出。
应用过程
- 正则表达式编译
- 传动开始
- 元素检测
- 寻找匹配结果
- 传动装置的驱动过程
- 匹配彻底失败
优化措施
常见优化措施
- 加速某些操作,如
\d+
,引擎对此有特殊的处理方案 - 避免冗余操作,忽略某些不必要的操作
- 避免重新编译
- 使用非捕获型括号
- 不要滥用括号和字符组
- 使用起始锚点
编译缓存
- 集成式
- 程序式
- 面向对象式
通过传动装置进行优化
- 字符串起始行锚点优化
- 隐式锚点优化
.+
.*
/字符串结束行锚点优化 - 子串识别优化
- 预查必须字符
- 长度判断
优化正则表达式本身
- 文字字符串链接优化 —> abc 为一个元素,作为匹配迭代的一个单元
- 化简量词优化 —> 把简单量词作为一个整体
- 消除无必要括号 —>
(?:.*)
与.*
等价取后者 - 忽略优先量词之后的字符优化 —> 如果文本字符跟在忽略优先量词后,只要引擎不触及文本字符,忽略优先量词作为匹配优先量词处理
- 过度回溯检测 —>
.*?
不能匹配长于回溯上限的字符 - 避免指数级匹配 —> 单个量词迭代次数不应比目标字符串的字符数量更多
- 使用占有优先量词削减状态 —> 每一轮迭代抛弃上一轮的备用状态
- 量词等价转换
\d\d\d\d
—>\d{4}