【要命的神奇bug】if條件 使用 正則表示式
阿新 • • 發佈:2020-12-15
今天在做一個輸入判斷,使用了正則,因為多處會用到,所以用了一個全域性變數來接收,這也沒問題
然後,出現了一個神奇的事情,我輸出正則表示式的結果為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,下一次呼叫時,就又能搜到了。