首页 > 其他分享 >js在循环中使用正则失效异常的坑

js在循环中使用正则失效异常的坑

时间:2023-04-29 23:31:48浏览次数:36  
标签:log _________ js 正则 regular 111 test 失效 element

1、异常案例:

使用正则匹配111

    const regular = /111/g; // 匹配111
    // console.log(regular.test('111')); // true 匹配成功
    // console.log(regular.test('111,111')); // true 匹配成功

    const list = [
        '111',
        '111',
        '111,111',
        '111,111'
    ];
    list.forEach((element, index) => {
        // 异常写法
        console.log('log_________' + regular.test(element));
    });  
    // 打印结果 
    // log_________true
    // log_________false // 会存在正则匹配为false的异常
	// log_________true
	// log_________true

why? 首先去MDN看了看正则的基础概念。 发现了lastIndex 这个属性

2、原因分析

    用正则表达式只要设置了全局匹配标志 /g ,test()方法 的执行就会改变正则表达式 lastIndex 属性。再循环中连续的执行 test() 方法,后面的执行将会从 lastIndex 数字处开始匹配字符串。 原来如此,看来test() 方法确实也不能随便滥用。 确认验证一下:

    const regular = /111/g; // 匹配111

    const list = [
        '111',
        '111',
        '111,111',
        '111,111'
    ];
    list.forEach((element, index) => {
        // 异常写法
        console.log('log_________' + regular.test(element));
        // 打印lastIndex
        console.info('logLastIndex___' + regular.lastIndex); 
    });  
    // 打印结果 
	// log_________true
	// logLastIndex___3
	// log_________false  // 确实因为lastIndex为3导致的
	// logLastIndex___0
	// log_________true
	// logLastIndex___3
	// log_________true
	// logLastIndex___7

3、解决方法1

上面我们发现正则test()方法有lastIndex属性,每次循环给恢复一下。

    const regular = /111/g; // 匹配111
	const list = [
        '111',
        '111',
        '111,111',
        '111,111'
    ];
    list.forEach((element, index) => {
        regular.lastIndex = 0;
        console.log('log_________' + regular.test(element)); // 打印正常
    });  

问题解决 OK了。

3、解决方法2

上面我们发现正则表达式设置了全局标志 /g 的问题,去掉/g全局匹配。(这个具体还得看自己的应用场景是否需要/g)

    const regular = /111/; // 去掉/g全局匹配
	const list = [
        '111',
        '111',
        '111,111',
        '111,111'
    ];
    list.forEach((element, index) => {
        console.log('log_________' + regular.test(element)); // 打印正常
    });  

OK了。

3、解决方法3

js有基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型。
基本数据类型:Number、String、Boolen、Undefined、Null、Symbol、Bigint。
引用数据类型:也就是对象类型Object type,比如:对象(Object)、数组(Array)、函数(Function)、日期(Date)、正则表达式(RegExp)。

so正则表达式属于引用数据类型,按传统思维肯定是需要“深拷贝”的,需要new 一个新Object。

    const regular = /111/g;
    const list = [
        '111',
        '111',
        '111,111',
        '111,111'
    ];
    list.forEach((element, index) => {
        // 正确写法 new RegExp的内存指向在循环过程中每次都单独开辟一个新的“对象”,不会和前几次的循环regular.test(xxx)改变结果而混淆
        // console.log('log_________' + /111/g.test(element)); // 这样写当然也行
        console.log('log_________' + new RegExp(regular).test(element)); // 打印OK了
    });  
    

OK了。

标签:log,_________,js,正则,regular,111,test,失效,element
From: https://blog.51cto.com/u_15650730/6237184

相关文章

  • 【模板方法设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
    简介模板方法模式(TemplateMethodPattern)也叫模板模式,是一种行为型模式。它定义了一个抽象公开类,包含基本的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤。不同的子类以不同的方式实现这些抽象方法,从而对剩余的逻辑有......
  • ubuntu安装nodejs 14
    nodejs的每个大版本号都有相对应的源,比如这里的10.x.x版本的源是https://deb.nodesource.com/setup_10.x。所以在终端执行:curl-sLhttps://deb.nodesource.com/setup_18.x|sudo-Ebash-点击查看命令解释这个命令是用来添加Node.js18.x的仓库地址。具体来说,它通过curl......
  • mapbox加载geojson报错error: Style is not done loading
    Mapbox加载GeoJSON地图时,遇到error:Styleisnotdoneloading错误通常是由于地图样式文件没有加载完成引起的。具体来说,可能是因为Mapbox样式文件中包含了某些需要加载的图片或者矢量图层,而这些图片或矢量图层尚未完全加载完成,导致无法渲染地图。为解决此问题,可以尝试以下......
  • 事务失效
    spring用代理对象去调用方法才会生效,在一个方法中去调用b其实是this去调用,所以不会生效 可以注入自己的service,用cglib代理的对象调用的b方法,可以让事务生效然后spring三级缓存会帮我们过滤循环依赖的问题         1.如果用了private就不会生效事务......
  • Fastjson检测和利用
    漏洞检测:`DNSlog{"@type":"java.net.InetAddress","val":"dnslog.cn"}在49以下才能触发,因为这个gadget在49被禁止了,可用于检测具体版本{"@type":"java.net.Inet4Address","val":"dnslog"}{"@type":"......
  • JS 设计模式
    单例模式一个类只有一个实例,并提供一个访问它的全局访问点。1classLoginForm{2constructor(){3this.state='hide'4}5show(){6if(this.state==='show'){7alert('已经显示')8return9......
  • js封装深拷贝方法
    deepCopy:function(data){ if(data===null||data===undefined){ returnnull; } letresult=Array.isArray(data)?[]:{}; if(data&&typeofdata==='object'){ for(letkeyindata){ if(data[key]&&typeof......
  • js循环调用接口,获取每一次接口的值
    vue代码。data数据:list:[{listName:"待办",listNum:0},{listName:"退回",listNum:0},{listName:"已办",listNum:0},{listName:"全部",listNum:0}],methods里面的方法:asyncgetAllData(){this.list.map((listItem,index)=&......
  • Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫
    Selenium和PhantomJS结合在一起,就可以运行一个非常强大的网络爬虫   测试人员的最佳11种开源自动化Selenium1)RobotFrameworkRobotFramework是一个开源自动化系统,它使用关键字驱动的方法进行验收测试驱动开发(ATDD)和验收测试。该工具组织了各种测试自动化要求......
  • ML-误差、偏差、过拟合、正则化
    机器学习在损失函数中加入正则项,称为Regularize正则化。目的是防止过拟合。原理是:加上限制后,缩小了解空间,从而减少过拟合的可能性。L0范数表示向量中非零元素个数,但L0范数的求解是个NP-Hard问题;L1范数也可以实现稀疏,而且更容易求解。L2范数不如L1范数更能够降低复杂度,但是处处可......