今天朋友問我一個問題,我如今須要屢次匹配同一個內容,可是爲何我第一次匹配,直接是 true,而第二次匹配確實 false 呢?html
var s1 = "MRLP"; var s2 = "MRLP"; var reg = /mrlp/ig; console.log(reg.test(s1)); console.log(reg.test(s2));
這時候你會發現,咱們在連續使用一個正則匹配其餘字符串的時候,第一次匹配是 true,而第二次匹配則是 false。正則表達式
等等,WHT?我匹配的是 MRLP,並且我還特地加上i
用於不區分大小寫,能夠爲何第一次能夠正常匹配,第二次就不行了呢?數組
這也就是我今天要跟你們說的,關於 JS 中的 lastIndex。函數
2. lastIndex
在開始講解以前,首先先帶你們簡單回顧一下 JS中正則表達式的使用方式。post
JS 中正則表達式的使用方式有兩種:this
第一種是正則表達式對象的方法,經常使用方法有兩個。spa
- exec(str) : 檢索字符串中指定的值。返回找到的值,並肯定其位置
- test(str) : 檢索字符串中指定的值。返回 true 或 false
第二種是字符串對象的方法,經常使用方法有四個。code
- match(regexp) : 找到一個或多個正則表達式的匹配,返回一個配配的數組(該數組的內容依賴於 regexp 是否具備全局標誌 g。)
- replace(regexp/substr,replacement) : 替換與正則表達式匹配的子串,返回一個新的字符串(replacement能夠是字符串或函數、lambda表達式)
- search(regexp) : 檢索與正則表達式相匹配的值,返回相匹配的子串的起始位置,不然返回 -1。(它將忽略標誌g和 lastIndex屬性,且老是從字符串的開始處進行檢索)
- split(search) : 把字符串根據正則匹配的字符,分割爲字符串數組,返回數組
參考:https://www.w3school.com.cn/jsref/jsref_obj_string.asp
regexp
而這些方法和我們今天所說的 lastIndex 有什麼關係呢?htm
lastIndex 屬性用於規定下次匹配的起始位置。
上次匹配的結果是由方法 RegExp.exec( )
和 RegExp.test( )
找到的,它們都以 lastIndex 屬性所指的位置做爲下次檢索的起始點。
這樣,就能夠經過反覆調用這兩個方法來遍歷一個字符串中的全部匹配文本。
並且須要注意,該屬性只有設置標誌 g才能使用。
既然已經知道這個東西的造成緣由,那麼解決起來就很是簡單了。
3.解決方案
3.1 第一種解決方案
如上面所述,咱們 lastIndex 屬性必需要設置 g 標籤才能使用。
那麼咱們在匹配的時候,能夠根據狀況,直接去掉 g 標籤就能夠啦。
var s1 = "MRLP"; var s2 = "MRLP"; var reg = /mrlp/i; console.log(reg.test(s1)); //true console.log(reg.test(s2)); //true
3.2 第二種解決方案
不少時候,咱們必需要執行 全局匹配( g ),這時候就不能使用第一種方案了。
其實,咱們的lastIndex 屬性是可讀可寫的。
只要目標字符串的下一次搜索開始,就能夠對它進行設置。
當方法 exec() 或 test() 再也找不到能夠匹配的文本時,它們會自動把 lastIndex 屬性重置爲 0。
這樣,咱們再次執行全局匹配的時候,就不會出現 false 的狀況了。
var s1 = "3206064928:MRLP:3206064928"; var s2 = "MRLP"; var reg = /mrlp/ig; console.log(reg.test(s1)); //true console.log(reg.lastIndex); //reg.lastIndex = 15 reg.lastIndex = 0; //這裏我將 lastIndex 重置爲 0 console.log(reg.test(s2)); //true