JS正規表示式從入門到入土(9)—— test方法以及它的那些坑

格子熊發表於2018-07-11

test方法

test方法介紹

RegExp.prototype.test(str)

test方法用於測試字串引數中是否存在匹配正規表示式模式的字串

test方法的使用

let reg = /w/

reg.test(`a`)       // true

reg.test(`$`)       // false

通過結果可以看出,如果測試字串引數存在匹配正規表示式模式的字串則返回true,否則返回false

test方法的那些坑

當正規表示式使用了全域性匹配時,test方法會出現如下的這種奇怪現象:

let reg = /w/g

reg.test(`ab`)      // true

reg.test(`ab`)      // true

reg.test(`ab`)      // false

reg.test(`ab`)      // true

可以看到,每輪的第三次匹配返回會變為true,但是,ab不是都符合reg嗎,返回都應該返回true才對。原因就在於上一節提到過的lastIndex屬性。

我們可以試試每次都執行test方法都打出reg的lastIndex方法:

let reg = /w/g
reg.lastIndex       // 0

reg.test(`ab`)      // true
reg.lastIndex       // 1

reg.test(`ab`)      // true
reg.lastIndex       // 2

reg.test(`ab`)      // false
reg.lastIndex       // 0

reg.test(`ab`)      // true
reg.lastIndex       // 1

看看結果,然後回憶下lastIndex的定義,你就明白原因了。

lastIndex屬性是當前表示式匹配內容的最後一個字元的後一位,用於規定下一次匹配的起始位置。

當進入正規表示式全域性模式時,每次使用test方法都會從lastIndex開始,匹配從lastIndex開始的子字串。比如例子中,第二次執行test方法時,此時,lastIndex已經變為2,子字串為空,所以reg不可能匹配上它。由於子字串匹配失敗,test方法返回false,並將lastIndex屬性置為0,重新開始一輪迴圈。

避免test中的坑的方法

第一種方法:test方法本身就是用來測試是否存在匹配正則的字串,不使用全域性模式一樣可以實現目的,所以第一種方法就是不適用全域性模式。

第二種方法:不將正則物件例項存在變數中,每次直接用正則物件例項呼叫test方法,不過這種方法對記憶體有所損耗,理論上不建議。

相關文章