正则表达式性能优化的探究( 二 )
1.贪婪模式(Greedy)顾名思义 , 就是在数量匹配中 , 如果单独使用 +、?、*或(min,max)等量词 , 正则表达式会匹配尽可能多的内容 。
例如 , 上面那个例子:
text = "abbc"regex = "ab{1,3}c"
就是在贪婪模式下 , NFA自动机读取了最大的匹配范围 , 即匹配 3 个 b 字符 。 匹配发生了一次失败 , 就引起了一次回溯 。 如果匹配结果是“abbbc” , 就会匹配成功 。
text = "abbbc"regex = "ab{1,3}c"
2.懒惰模式(Reluctant)在该模式下 , 正则表达式会尽可能少地重复匹配字符 , 如果匹配成功 , 它会继续匹配剩余的字符串 。
例如 , 上面的例子的字符后面加一个“?” , 就可以开启懒惰模式 。
text = "abc"regex = "ab{1,3}?c"
匹配结果是“abc” , 该模式下 NFA 自动机首先选择最小的匹配范围 , 即匹配 1 个 b 字符 , 因此就避免了回溯问题 。
3.独占模式(Possessive)同贪婪模式一样 , 独占模式一样会最大限度地匹配更多内容;不同的是 , 在独占模式下 , 匹配失败就会结束匹配 , 不会发生回溯问题 。
还是上面的例子 , 在字符后面加一个“+” , 就可以开启独占模式 。
text = "abbc"regex = "ab{1,3}+c"
结果是不匹配 , 结束匹配 , 不会发生回溯问题 。
所以综上所述 , 避免回溯的方法就是:使用懒惰模式或独占模式 。
前面讲述了“Split() 方法使用了正则表达式实现了其强大的分割功能 , 而正则表达式的性能是非常不稳定的 , 使用不恰当会引起回溯问题 。 ” , 比如使用了 split 方法提取域名 , 并检查请求参数是否符合规定 。 split 在匹配分组时遇到特殊字符产生了大量回溯 , 解决办法就是在正则表达式后加一个需要匹配的字符和“+”解决了回溯问题:
\\?(([A-Za-z0-9-~_=%]++\\ --tt-darkmode-bgcolor: #131313;">五.正则表达式的优化1. 少用贪婪模式 :多用贪婪模式会引起回溯问题 , 可以使用独占模式来避免回溯 。
2. 减少分支选择 :分支选择类型 “(X|Y|Z)” 的正则表达式会降低性能 , 在开发的时候要尽量减少使用 。 如果一定要用 , 可以通过以下几种方式来优化:
1)考虑选择的顺序 , 将比较常用的选择项放在前面 , 使他们可以较快地被匹配;
2)可以尝试提取共用模式 , 例如 , 将 “(abcd|abef)” 替换为 “ab(cd|ef)”, 后者匹配速度较快 , 因为 NFA 自动机会尝试匹配 ab , 如果没有找到 , 就不会再尝试任何选项;
3)如果是简单的分支选择类型 , 可以用三次 index 代替 “(X|Y|Z)”, 如果测试话 , 你就会发现三次 index 的效率要比 “(X|Y|Z)” 高一些 。
3. 减少捕获嵌套 :
捕获组是指把正则表达式中 , 子表达式匹配的内容保存到以数字编号或显式命名的数组中 , 方便后面引用 。 一般一个()就是一个捕获组 , 捕获组可以进行嵌套 。
非捕获组则是指参与匹配却不进行分组编号的捕获组 , 其表达式一般由(?:exp)组成 。
在正则表达式中 , 每个捕获组都有一个编号 , 编号 0 代表整个匹配到的内容 。 可以看看下面的例子:
public static void main(String[] args) {String text = "test";String reg = "(
如果你并不需要获取某一个分组内的文本 , 那么就使用非捕获组 , 例如 , 使用 “(?:x)” 代替 “(X)”, 例如下面的例子:
public static void main(String[] args) {String text = "test";String reg = "(?:
作者:huangrenhui
出处:
- 巅峰|realme巅峰之作:120Hz+陶瓷机身+5000mAh 做到了颜值与性能并存
- 华为|骁龙870和骁龙855区别都是7nm芯片吗 性能对比评测
- 器件|苏州纳米所等在高性能柔性储能器件研究中取得进展
- 超强|RedmiNote9系列发布!天玑800U赋予超强5G性能
- iPhoneX|iPhone12和iPhoneX性能对决:差距比想象的大太多
- Redmi|Redmi Note 9系列发布,搭载天玑800U具备超强5G性能
- 首发|华为或首发联发科6纳米+A78新U:性能超强不输麒麟9000
- 华为|安兔兔10月安卓性能榜:华为Mate40 Pro第一 麒麟9000碾压骁龙865
- 骁龙865|5G手机中的性能怪兽,256+120W闪充,比iPhone12值得买
- 网间|新外观专利陆续曝光 徐起和网间透露realme极致性能新机将至