【神奇的BUG】在使用正则表达式时,结果明明是 true,不走 if 却走 else,但是此时既不是 true也不是false,请看我如何狡辩
前言
在进行需求开发时,碰到了一个神奇的、莫名的Bug。
在项目中,我用到了正则表达式,出于职业操作,我先把它声明定义出来,没毛病吧。
然后继续,我要判断一下我的输入是否符合当前的正则规则。
此时,神奇的事情发生了。。。
我输入的内容正则表达式判断结果我 true,但是 if 的判断结果却是 false 走了 else

WHAT????
甚是疑惑,一度以为是我眼花了,那先上问题代码
代码
let value = "0";
const regExp = /\d/g;
// \d => 匹配一个数字字符,等价于[0-9]
// g => 是全局匹配
console.log("判定", regExp.test(value));
if (regExp.test(value)) {console.log("进入了true")
} else {console.log("进入了false")
}
输出结果:
判定 true
进入了false
是不是很疑惑,上面的正则判断的结果明明是 true,可是为什么还会走 else 呢???

听我狡辩
其实,你没错,他也没错,都是缘分惹的祸。。。
首先 const regExp = /\d/g; 声明的正则表达式 (g) 为全局匹配模式
简单来说,全局匹配模式就是对指定校验字符串的多次校验,每一次校验会改变它的 lastIndex 值,lastIndex 属性的初始值为 0,每次找到匹配的项后,lastIndex 的值就被重置为匹配内容的下一个字符在字符串中的位置索引,用来标识 下次执行匹配时开始查找的位置 。
如果找不到匹配的项 lastIndex 的值会被设置为 0。
看到这,有可能你很迷惑。那么来看一下下面的代码:
console.log("判定", regExp.test(value));
此时,为第一次校验,执行完该代码之后, lastIndex 值将从 0 变为 1。
if (regExp.test(value))
到这,为第二次校验,此时 lastIndex 已经变为 1 了。
什么?不信??那么我们打印一下看看结果就知道了。。。
let value = "0";
const regExp = /\d/g;
console.log("未校验前:", regExp.lastIndex);
console.log("判定", regExp.test(value));
console.log("第一次校验:",regExp.lastIndex);
if (regExp1.test(value)) {console.log("进入了true")
} else {console.log("进入了false")
}
结果:
未校验前: 0
判定 true
第一次校验: 1
进入了false
看,没有骗你吧。
那么,你还记得 lastIndex 的作用是什么吗?
lastIndex 用来标识 下次执行匹配时开始查找的位置,所以在下次执行 if 时当然校验不到了。
另一个怪异事件,此时的校验结果既不是 true 也不是 false
let value = "0";
const regExp = /\d/g;
console.log("判定", regExp.test(value));
if (regExp.test(value) === true) {console.log('true');
}else if(regExp.test(value) === false) {console.log('false');
}else {console.log('其它');
}
结果:
判定 true
其它
至于为什么会出现上面提到的既不是 true 也不是 false 的原因,这是因为: else if 中又做了一次校验,前文中也有提到,即:如果找不到匹配的项 lastIndex 的值会被设置为 0,所以校验值会在 true 和 false 之间变化。
解决方案
上面狡辩的也差不多了,大家伙应该也都看明白到底是怎么回事啦,那么我再给出两个解决方案吧:
1. 不使用全局校验
这是最简单的方法了,把表达式校验改为:
const regExp = /\d/;
去掉全局匹配 (g) 就可以了。
如果不使用全局校验,那么,lastIndex 在每次的检验中都为 0。
2. 还想使用全局校验
如果还想使用全局校验,那就把
console.log("判定", regExp.test(value));
这行代码删掉就可以了。
3. 在不删除 console.log 打印前提下,还想使用全局校验
在它的下面重新设置 lastIndex = 0 即可。
let value = "0";
const regExp = /\d/g;
console.log("判定", regExp.test(value));
regEx.lastIndex = 0;
if (regExp1.test(value)) {console.log("进入了true")
} else {console.log("进入了false")
}
这样相当于将它的 lastIndex 重新设置为 0,不会影响后续操作。
总结
看了我有理有据的狡辩,是不是对这个问题彻底明白了。
如果这个文章对您有所帮助,欢迎一键三连哦~
各位,加油!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
