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了。