前言

有时候需要实现对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正则表达式匹配字符串与优化过程的更多相关文章

  1. JS正则表达式获取字符串中特定字符

    JS正则表达式获取字符串中得特定字符,通过replace的回调函数获取. 实现的效果:在字符串中abcdefgname='test'sddfhskshjsfsjdfps中获取name的值test  实 ...

  2. js正则匹配字符串

    这里我第一时间想到的就是用 js 的search 和 match ,其中最常见的是match: 1. str.search(regexp):search()方法不支持全局搜索,因为会忽略正则表达式参数 ...

  3. java中使用正则表达式匹配字符串

    在Java中使用正则表达式去匹配相应的字符串: String importFileRole = "(import)\\s*[a-zA-Z0-9_<>.]+\\;";// ...

  4. js正则表达式匹配斜杠 网址 url等

    项目中有个需求,需要从url中截取ID.需要在前台用js匹配截取,所以就百度一下,发现都没有说清楚,所以这里就总结下. 正则表达式如下: var epId=0; //工厂企业ID var urlInd ...

  5. 【SQL查询】正则表达式匹配字符串

    1. 元字符说明 元字符 含义 ^ 匹配输入字符串的开始位置. $ 匹配输入字符串的结尾位置. * 匹配前面的字符零次或多次. + 匹配前面的字符一次或多次. ? 匹配前面的字符零次或一次. . 匹配 ...

  6. C#正则表达式匹配字符串

    正则表达式可以快速判断所给字符串是否某种指定格式.这里将一些常用的方法封装进一个字符串工具类中. public static class StringTool { /// <summary> ...

  7. JS正则表达式匹配域名 网址 URL

    DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母.标号中除连字符(-)外不能使用其他的标点符号.级别最低的域名写在最左边,而级别最高的域名写在最右边.由多 ...

  8. JS正则表达式匹配<div><style>标签

    测试字符串: <style>v\:* {                 BEHAVIOR: url(#default#VML) } o\:* {                 BEHA ...

  9. JS 正则表达式转换字符串

    获取第一个.前面的字符串,以及后面的字符串: const transform = str => { str.replace(/([^\.]*)\.(.*)/, function($0, $1,$ ...

随机推荐

  1. nodemailer中的几个坑

    nodemailer是什么 nodemailer是一个nodejs的邮件服务模块 如何用nodemailer发邮件 1.先安装nodemailer npm i --save nodemailer 2. ...

  2. CentOS7.0安装Nginx

    安装Nginx yum install nginx 正常情况下必定是: 已加载插件:fastestmirror, langpacks base | :: docker-main | :: extras ...

  3. jQuery写选项卡

    <!DOCTYPE html> <htmllang="en"> <head> <metacharset="UTF-8" ...

  4. 屏幕适配基础——了解:ppi、dpi、px、sp、dp

    做android开发绕不开的几个名词:ppi.dpi.px.sp.dp.那么它们的定义.区别和联系都是什么呢?这篇博客系统的做一个概述和总结. 1.基本概念 px:pixel,像素,电子屏幕上组成一幅 ...

  5. js中字符串转换为数值的两种方法的区别

    在js中字符串转换为数值的方法有三种:转换函数,强制类型转换,隐式转换 1.转换函数 parseInt()   //将字符串转换为整型 parseFloat()  //将字符串转换为浮点型 转换函数在 ...

  6. Phpcms 详情页显示所属栏目的同级栏目

    Phpcms详情页是不显示所属栏目的同级栏目的,如果按下面的方式 {loop subcat($parentid) $v} <li{if $v[catid]==$catid} class=&quo ...

  7. 移动端利用rem实现自适应布局

    好久没有写博客了,刚好说说最近遇到的移动端布局问题吧. 本来一直是觉得我的页面布局能力还是不错的,当然,是相对于较基础的来说还是不错的.不过,自己写的案例终归是跟实际开发有区别的,自己写案例的是觉得这 ...

  8. StringBuffer与StringBuilder的区别,及实现原理

    区别 1.StringBuffer 与 StringBuilder 中的方法和功能完全是等价的, 2.只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是 ...

  9. Node软件的安装

    1.官网网址:https://nodejs.org/en/ 左边被推荐,右边最新 下载完成一键下一步直接安装,当然,如果你想修改安装目录的话当然没问题,注意:不要有英文目录 2.Window+r打开命 ...

  10. RecyclerView 设置item间隔的方法

    RecyclerView大家常用,但是如何给加载出来的item增加间隔很多人都不知道,下面是方法,直接上代码了: LinearLayoutManager layoutManager = new Lin ...