js正则表达式匹配字符串与优化过程
前言
有时候需要实现对js源文件中的url字符串做拦截预处理,或者前端js语法高亮,或者需要对动态加载的关键源码做混淆保护,在某些步骤实现之前,有一个步骤是需要提炼出所有的合法字符串。
目标:检测源文件文本中的字符串,合法的双(单)引号之间的内容与引号自身。
实现方式:正则表达式匹配。
改进:优化正则表达式,加快匹配速度与尽可能减少匹配时占用的内存空间。
基本存在情况:“”,’’,”\””,’\’’,所有的合法字符情况都是以上四种情况的拓展
分解规则:双引号之间存在双引号,前面必须是转义符 “\”,单引号同理。所以匹配到后面一个引号时,必须检测前面是是否存在连续奇数长度的转义符”\”。
比如:
”\””,”\\\””,”\\\\\”” 正确匹配目标是3个”\””,”\\\””,”\\\\\””。
a = "\\";"test".split(""); 正确匹配目标是3个:”\\”, “test”,””, 而不是2个"\\";",".split(";。
但是js中暂时不支持正向反查的形式(?<!),需要转换下思路:
根据正则从左到右的顺序,优先判断一组转义\”或者\’,,使用 /” (\\.|.)+?”/g
例如:”\\\””;all
1:匹配起始” --> “
2:第一位\与第二位\不能组成\”,符合任意字符匹配”.”,下一步 --> “\
3:第二位\与第三位\不能组成\”,符合任意字符匹配”.”,继续下一步 --> ”\\
4:第三位\与第四位” 可以组成\”, 继续下一步 --> ”\\\”
5:第五位是”, 匹配结束” --> 得到目标字符串 --> ”\\\””
第一次正则表达式
/""|"(\\"|.)+?"|''|'(\\'|.)+?'/gm
测试:
'aa,\"\'\",,aa,,,bbbb,,,,\\\',,cc,dd,';test, ==> 'aa,\"\'\",,aa,,,bbbb,,,,\\\',,cc,dd,' 1
"" ==>""
'' ==>''
"\\" ==>"\\"
"\'\\\"" ==>"\'\\\""
"\"\"" ==> "\"\""
达到效果预期。
优化正则表达
原始版: /""|"(\\"|.)+?"|''|'(\\'|.)+?'/gm
优化第1版:/\"(\\"|.)*?\"|\'(\\'|.)*?\'/gm
优化第2版:/("|')(\\.|.)*?\1/gm 或者 /(["'])(\\["']|.)*?\1/gm 或者 /("|')(?:\\.|.)*?\1/gm
其中2是1的字面简化写法,但是对比1与2,2多了一个\1,正则表达式需要缓存开始位("|')用于结束位匹配,放弃2。
那么1是否可以再优化?
可以:使用非捕获型,减少捕获缓存
最终效果:
/\"(?:\\"|.)*?\"|\'(?:\\'|.)*?\'/gm
后记
测试中只有达到400万长度的字符串才会有明显的性能差,400万长度在chrome浏览器中是【2:380ms】【1(终版):180ms】,一般来说,正常使用的文本不会这么长到变态,所以最终优化版与前面几个版本之间的性能在正常情况下的差距几乎可以忽略不及,最终优化版只是一种自嗨的高潮而已。因为这样很爽啊。
推荐一个老外写的js正则表达式可视化,: https://github.com/JexCheng/regulex


可视化的正则表达式真好看,end!
Bruce-CZ原创
----看着流莺的羽毛一点点暗淡下去,他觉得好像什么东西死去一样,堵住喉咙一样难受,是什么呢,他又说不出。
js正则表达式匹配字符串与优化过程的更多相关文章
- JS正则表达式获取字符串中特定字符
JS正则表达式获取字符串中得特定字符,通过replace的回调函数获取. 实现的效果:在字符串中abcdefgname='test'sddfhskshjsfsjdfps中获取name的值test 实 ...
- js正则匹配字符串
这里我第一时间想到的就是用 js 的search 和 match ,其中最常见的是match: 1. str.search(regexp):search()方法不支持全局搜索,因为会忽略正则表达式参数 ...
- java中使用正则表达式匹配字符串
在Java中使用正则表达式去匹配相应的字符串: String importFileRole = "(import)\\s*[a-zA-Z0-9_<>.]+\\;";// ...
- js正则表达式匹配斜杠 网址 url等
项目中有个需求,需要从url中截取ID.需要在前台用js匹配截取,所以就百度一下,发现都没有说清楚,所以这里就总结下. 正则表达式如下: var epId=0; //工厂企业ID var urlInd ...
- 【SQL查询】正则表达式匹配字符串
1. 元字符说明 元字符 含义 ^ 匹配输入字符串的开始位置. $ 匹配输入字符串的结尾位置. * 匹配前面的字符零次或多次. + 匹配前面的字符一次或多次. ? 匹配前面的字符零次或一次. . 匹配 ...
- C#正则表达式匹配字符串
正则表达式可以快速判断所给字符串是否某种指定格式.这里将一些常用的方法封装进一个字符串工具类中. public static class StringTool { /// <summary> ...
- JS正则表达式匹配域名 网址 URL
DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母.标号中除连字符(-)外不能使用其他的标点符号.级别最低的域名写在最左边,而级别最高的域名写在最右边.由多 ...
- JS正则表达式匹配<div><style>标签
测试字符串: <style>v\:* { BEHAVIOR: url(#default#VML) } o\:* { BEHA ...
- JS 正则表达式转换字符串
获取第一个.前面的字符串,以及后面的字符串: const transform = str => { str.replace(/([^\.]*)\.(.*)/, function($0, $1,$ ...
随机推荐
- JTextArea与TextArea自动换行和滚动条的区别对比
最近在用Java写一个仿记事本的程序,但是发现用JTextArea写的效果有点差,但是用TextArea自动换行并不那么方便,经过对比和实践,我也发现自己对这两个标签认识存在不足,下面就来讨论一下他们 ...
- linux下c++动态库的生成及使用
文章来源于:http://hi.baidu.com/ablenavy/item/b498901c6826bbf587ad4e33 我的程序是一个类,在网上找了半天,都是c的例子,c++的类封装成静态库 ...
- 轻松理解python中的闭包和装饰器 (下)
在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...
- jvm系列(八):jvm知识点总览-高级Java工程师面试必备
在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...
- 每天一个linux命令(55)--at命令
在Windows系统中,Windows提供了计划任务这一功能,在控制面板 -> 性能与维护 -> 任务计划,它的功能就是安排自动运行的任务.通过 ‘ 添加任务计划’ 的一步步引导, ...
- JS中的onclick事件
原文链接:https://segmentfault.com/q/1010000007955542?_ea=1503986 我自己做了一下测试. 这个是在html里面直接绑定onclick事件,我打印了 ...
- 完全理解Python迭代对象、迭代器、生成器
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
- 《C#语言和数据库技术基础》单词必备
<C#语言和数据库技术基础> 第一章1..NET Framework 框架2.sharp 尖锐,强烈的3.application 应用程序4.devel ...
- 使用ocupload和POI一键上传Excel并解析导入数据库
使用的工具如下: JQuery ocupload jquery.ocupload-1.1.2.js Apache POI poi-3.9.jar 如果是Maven项目添加依赖如下: <depe ...
- how to use Prolog in C#? SWI-Prolog
上个月突然看到Prolog这门语言,它特殊的语法吸引了我,但是经过我一段时间的学习,发现它也不像网络上传说的那样神奇,不过我依然对它很感兴趣,有前辈说Prolog本身并不强大,但是用来作为一门辅助语言 ...