参考文章:
https://www.zhihu.com/question/48219401/answer/1476436385
mark一个好用的正则测试网站
https://regex101.com/
一、避免量词嵌套
/a*b/
和/(a*)*b/
去匹配aaaaa
,前者的匹配步数远远小于后者。可见,嵌套量词会大大增加正则的执行过程。因为这其中进行了两层回溯,这个执行步骤增加的过程就如同算法复杂度从 O(n)上升到 O(n^2)的过程一般。
所以面对量词嵌套,我们需作出适当的转化消除这些嵌套:
(a*)* ⇋ (a+)* ⇋ (a*)+ ⇋ a*
(a+)+ ⇋ a+
二、使用非捕获组
NFA 正则引擎中的括号主要有两个作用:
- 主流功能,提升括号中内容的运算优先级
- 反向引用backreference
反向引用这个功能很强大,强大的代价是消耗性能,因为()
会把相关匹配存储到一个临时缓冲区。所以,当我们如果不需要用到括号反向引用的功能,即访问某缓冲区时,我们应该尽量使用非捕获组,也就是:
// 捕获组与非捕获组
() ⇒ (?:)
三、分支优化
1.减少分支数量
e.g.
/^http|https/
优化为:
/^https?/
来减少没必要的分支回溯。
2.缩小分支内的内容
e.g.要匹配 this 和 that,正则:
/this|that/
优化为:
/th(?:is|at)/
第一个正则的执行步骤比第一个正则多两步,第一个正则的回溯路径比第二个正则的回溯路径更长了,最终导致执行步骤变长
四、锚点优化
在能使用锚点的情况下尽量使用锚点,即定位符。大部分正则引擎会在编译阶段做些额外分析,判断是否存在成功匹配必须的字符或者字符串。类似^
、$
这类锚点匹配能给正则引擎更多的优化信息。
例如正则表达式 hello(hi)?$
在匹配过程中只可能从字符串末尾倒数第 7 个字符开始, 所以正则引擎能够分析跳到那个位置,略过目标字符串中许多可能的字符,大大提升匹配速度。
五、不使用正则表达式
有时优化太差不用更好,直接上字符串操作好耶
六、避免性能问题影响页面响应
在必须使用正则表达式,且的确有潜在的性能问题的情况下。要避免正则表达式的性能影响到页面响应。一种可能的方式是像 regex101 一样把正则表达式的匹配操作放到 Service Worker中进行。
网上看的,似乎是js方面的,这个不太了解。