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,$ ...
随机推荐
- BZOJ 4089:[Sdoi2015]graft(SDOI 2015 Round 2 Day 2)
别人家的神选系列,我只会做这道题QAQ 题目描述: 给定一颗树,加上k条边,将n个点染色,相邻两点不同,记颜色为i的又ti个,求$$\frac{\sum_{i=1}^{n} \frac{ti}{i}} ...
- 学习笔记——Java类和对象
今天学习了Java的类和对象的相关知识,由于Java面向对象的编程的思想和C++几乎一样,所以需要更多的关注Java的一些不同之处. 1.类 1.1 在类这一块,除了基本的成员变量,成员方法,构造函数 ...
- Linux 下文件操作 shell
删除目录下的所有文件ls *.log | xargs rm -f当前目录所有文件大小的总和ll | awk '{sum += $5}; END {print sum/1048576}'将命令推送到后台 ...
- Easyui _treegrid 动态加载子节点
<table id="dg" class="easyui-treegrid" title="数据字典列表" data-options= ...
- Python基础入门教程(4)(数据类型)
人生苦短,我学Pyhton Python(英语发音:/ˈpaɪθən/), 是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于199 ...
- 【Java每日一题】20170308
20170307问题解析请点击今日问题下方的"[Java每日一题]20170308"查看(问题解析在公众号首发,公众号ID:weknow619) package Mar2017; ...
- 寻找与疾病相关的SNP位点——R语言从SNPedia批量提取搜索数据
是单核苷酸多态性,人的基因是相似的,有些位点上存在差异,这种某个位点的核苷酸差异就做单核苷酸多态性,它影响着生物的性状,影响着对某些疾病的易感性.SNPedia是一个SNP调査百科,它引用各种已经发布 ...
- mongoDB & Nodejs 访问mongoDB (二)
非常详细的文档http://mongodb.github.io/node-mongodb-native/2.2/quick-start/quick-start/ 连接数据库 安装express 和 m ...
- Mditor 发布「桌面版」了 - http://mditor.com
简单说明 Mditor 最早只有「组件版」,随着「桌面版」的发布,Mditor 目前有两个版本: 可嵌入到任意 Web 应用的 Embed 版本,这是一桌面版的基础,Repo: https://git ...
- 3555: [Ctsc2014]企鹅QQ
3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 696 Solved: 294[Submit][Status ...