目录
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? 首先去看了看。
发现了。
2、原因分析
用正则表达式只要设置了全局匹配标志 /g , 的执行就会改变正则表达式 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了。