js 正则学习小记之匹配字符串字面量优化篇

 

昨天在《js 正则学习小记之匹配字符串字面量》谈到 /"(?:\.|[^"])*"/ 是个不错的表达式,因为可以满足我们的要求,所以这个表达式可用,但不一定是最好的

昨天在《js 正则学习小记之匹配字符串字面量》谈到 /"(?:\.|[^"])*"/ 是个不错的表达式,因为可以满足我们的要求,所以这个表达式可用,但不一定是最好的。

从性能上来说,他非常糟糕,为什么这么说呢,因为 传统型NFA引擎 遇到分支是从左往右匹配的,

所以它会用 \. 去匹配每一个字符,发现不对后才用 [^"] 去匹配。

比如这样一个字符串: "123456'78"90"

共 16 个字符,除了第一个 " 直接匹配成功,还剩余 15 个,只有 2 个转义(4 个字符),所以 \. 会失败 10 次,只有 2 次成功。

这 10 次匹配失败,需要回溯后用 [^"] 才能匹配成功,当然最后一个 " 会直接匹配成功。

很明显,正常的字符串不可能全是转义,正常的字符串才是主流,当然不排除有人故意全转义的情况。

所以这个正则需要10次回溯后才能匹配完成,如果字符串增长到 1K 1M 肿么破呢?

所以我们要修改下这个正则,前后换下位置么?

js 正则学习小记之匹配字符串字面量优化篇

js 中 字符串用 折行是允许的,但是修改后的 正则 没法匹配这样的字符串了,所以我们还得继续修复。

因为 . 没法匹配换行,所以我们要用其他方式表达。

. 是用于匹配除换行符之外的所有字符,难道我们要 [.n] 来表示么?

这样是不对的,因为 [] 字符集中的 . 不再表示除换行符之外的所有字符,而是字符 . 也就是他本身一个字符而已。

那怎么办呢?

其实换个思路,

d 表示 0-9

D 表示 [^0-9]

那么 [dD] 就表示所有了,不是么。(新人朋友不知道能不能消化这个知识点。)

同理 [sS] [wW] 同样可以。

所以 /"(?:[^"\]|\[dD])*"/ 这样就满足我们的要求了。

js 正则学习小记之匹配字符串字面量优化篇

效果不错。

回头过来分分析下他现在的性能吧。

还是这个字符串: "123456'78"90" , 正则 /"(?:[^"\]|\[dD])*"/

共 16 个字符,除了第一个 " 直接匹配成功,还剩余 15 个,有 2 个转义(4 个字符),[^"\] 能匹配成功 10 个字符,只有 2 次失败。

为什么不是 4 次失败呢,明明有4个字符啊。\ 虽然是2个字符,但是读到第一个 就匹配失败,然后用 \[dD] 匹配成功,

占用掉了两个字符 \ 下次用下一个o开始匹配,所以只有2次回溯。

只有 2 次需要回溯,然后用 \[dD] 匹配成功。当然最后一个 " 还是会直接匹配成功。

所以从 10 次回溯,减少到了 2 次,虽然正则比昨天臃肿了很多,但至少性能提升了不止一个等级。

OK,今天的分享完毕,明天见。

来源:脚本之家

链接:https://www.jb51.net/article/184337.htm

免责申明:
1. 本站所有下载资源均不包含技术支持和安装服务!需要讨论请进群!
2. 分享目的仅供大家学习和交流,请不要用于商业用途!
3. 如果你也有好源码或者教程,可以到审核区发布,分享有KR奖励和额外收入!
4. 如有链接无法下载、失效或广告,请联系管理员处理!
5. 本站无法保证资源或破解时效性,如某些授权码过期等问题,恕不在修复范围内。
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!故不接受任何形式的退款,如确认资源确有问题的,会补给相应KR以供再次购买。
7. 53Kr源码暂未发现后门代码,但无法保证100%安全,推荐检测方法:上传到 https://www.virustotal.com/在线查看是否有恶意代码以及其他有后门嫌疑的代码。
8. 在本站下载的源码我还是不建议正式使用,有特别喜欢的可以去程序官方购买。
53kr资源站仅提供学习的平台,所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,并不承担任何法律责任,如果对您的版权或者利益造成损害,请提供相应的资质证明,我们将于3个工作日内予以删除。
53kr资源分享 » js 正则学习小记之匹配字符串字面量优化篇

发表回复