心辰·Dev

正则表达式的性能优化

声明:本文整理自《精通正则表达式》

正则表达式匹配原理

匹配基础

  • 优先选择最左端的匹配结果。
  • 标准匹配量词 + ? 匹配优先。

回溯原则

如果需要在“进行尝试”和“跳过尝试”之间选择,对于匹配优先量词,引擎会优先选择“进行尝试”,对于忽略优先量词,会选择“跳过尝试”。
距离当前最近储存的选项就是当本地失败强制回溯时返回的。使用的原则是 LIFO 后进先出。

应用过程

  1. 正则表达式编译
  2. 传动开始
  3. 元素检测
  4. 寻找匹配结果
  5. 传动装置的驱动过程
  6. 匹配彻底失败

优化措施

常见优化措施

  • 加速某些操作,如 \d+,引擎对此有特殊的处理方案
  • 避免冗余操作,忽略某些不必要的操作
  • 避免重新编译
  • 使用非捕获型括号
  • 不要滥用括号和字符组
  • 使用起始锚点

编译缓存

  • 集成式
  • 程序式
  • 面向对象式

通过传动装置进行优化

  • 字符串起始行锚点优化
  • 隐式锚点优化 .+ .*/字符串结束行锚点优化
  • 子串识别优化
  • 预查必须字符
  • 长度判断

优化正则表达式本身

  1. 文字字符串链接优化 —> abc 为一个元素,作为匹配迭代的一个单元
  2. 化简量词优化 —> 把简单量词作为一个整体
  3. 消除无必要括号 —> (?:.*).*等价取后者
  4. 忽略优先量词之后的字符优化 —> 如果文本字符跟在忽略优先量词后,只要引擎不触及文本字符,忽略优先量词作为匹配优先量词处理
  5. 过度回溯检测 —> .*?不能匹配长于回溯上限的字符
  6. 避免指数级匹配 —> 单个量词迭代次数不应比目标字符串的字符数量更多
  7. 使用占有优先量词削减状态 —> 每一轮迭代抛弃上一轮的备用状态
  8. 量词等价转换\d\d\d\d —> \d{4}