【要命的神奇bug】if条件 使用 正则表达式
今天在做一个输入判断,使用了正则,因为多处会用到,所以用了一个全局变量来接收,这也没问题
然后,出现了一个神奇的事情,我输出正则表达式的结果为false
,但是if的判断却走了true
???? WTF????
代码大致如下
// 判断密码正则
const passwordPatern = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\!\@\#\$\%\^\*\(\)])[a-zA-Z0-9\!\@\#\$\%\^\*\(\)]{8,17}$/g
// 判断密码
let tm
esui.get('password').on('input', function () {
clearTimeout(tm)
// 节流
tm = setTimeout(() => {
console.log(this.getValue(), passwordPatern.test(this.getValue()))
if (passwordPatern.test(this.getValue())) {
console.log('1')
}
else {
console.log('密码不符合要求')
}
}, 800);
})
密码符合要求应该会输出1
测试结果却出人意料,console明明输出了true
,密码符合要求,却走了else,WTF!!! 这就令人匪夷所思了
难道if的判断有bug?经过多次试验测试,if(false)肯定不会执行,使用一个变量接收正则判断的结果后,也不会出现那个问题
所以,这应该是正则表达式的问题
那么,正则表达式有什么问题呢,经过进一步测试,passwordPatern.test('q123456!')
的结果不是固定的,一会儿为true
,一会儿为false
我知道鼠标放上去会执行一次js获取结果,所以大胆的想一想,这个正则的执行结果会变,但是又觉得不科学啊
又写了一个简单的测试用例
const exp = /abc/g
console.log(exp.test('abc'))
console.log(exp.test('abc'))
console.log(exp.test('abc'))
这个会输出3个true吗?
输出结果
为什么会输出false呢?这就是正则的一个特性了(坑坑坑)
去搜索了一圈,在MDN的网站上,找到这么一句:
test called multiple times on the same global regular expression instance will advance past the previous match.
因为例子中的正则带了g,所以每次调用test方法会先获取一个隐藏属性lastIndex,会跳过上次已经搜索过的部分。
第偶数次调用test的时候,就从前一次的lastIndex开始搜索。结果搜不到,就返回false。lastIndex置为0,下一次调用时,就又能搜到了。