javascript - js正規如果使用^和$再使用g會很怪異,但不報錯
伊谢尔伦
伊谢尔伦 2017-05-19 10:40:32
0
2
513
var reg1 =  /^1$/g;
var reg2 = /^1$/;
for (var i = 0; i < 10; i++) {
    console.log(reg1.test('1')) // true false true false true false true false ...
    console.log(/^1$/g.test('1')) // true  true  true  true  true  true  true ...
    console.log(reg2.test('1')) // true  true  true  true  true  true  true ...
    console.log(/^1$/.test('1')) // true  true  true  true  true  true  true ...
}

為什麼第一條console.log的輸出會是這樣?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回覆(2)
世界只因有你

正規執行時, RegExp物件的lastIndex可能會改變.

test 方法用於偵測字串是否符合某個正規規則, 只要是字串中含有與正規規則相符的文字, 該方法就傳回true, 否則傳回 false.

實際上, 如果正規表示式帶有全域標誌(帶有參數g)時, test 方法還受正規物件的lastIndex屬性影響,如下:

var reg = /[a-z]+/;//正则不带全局标志
console.log(reg.test("abc"));//true
console.log(reg.test("de"));//true

var reg = /[a-z]+/g;//正则带有全局标志g
console.log(reg.test("abc"));//true
console.log(reg.lastIndex);//3, 下次运行test时,将从索引为3的位置开始查找
console.log(reg.test("de"));//false

該影響將在exec 方法講解中予以分析.

exec 方法用於偵測字串對正規表示式的符合, 如果找到了符合的文字, 則傳回一個結果陣列, 否則傳回null.

語法: exec(string)

exec 方法傳回的陣列中包含兩個額外的屬性, index 和 input. 並且該陣列具有以下特點:

  • 第 0 項表示正規表示式捕獲的文字

  • 第 1~n 項表示第 1~n 個反向引用, 依序指向第 1~n 個分組捕獲的文本, 可以使用RegExp.$ + "編號1~n" 依次獲取分組中的文本

  • index 表示匹配字串的初始位置

  • input 表示正在檢索的字串

無論正規表示式有無全域標示"g", exec 的表現都相同. 但正規表示式物件的表現卻有些不同. 下面我們來詳細說明下正規表示式物件的表現都有哪些不同.

假設正規表示式物件為 reg , 偵測的字元為 string , reg.exec(string) 傳回值為 array.

若reg 包含全域標示"g", 那麼reg.lastIndex 屬性表示原字串中匹配的字串末尾的後一個位置, 即下次匹配開始的位置, 此時reg.lastIndex == array.index(匹配開始的位置) + array[0].length(匹配字串的長度). 如下:

var reg = /([a-z]+)/gi,
    string = "World Internet Conference";
var array = reg.exec(string);
console.log(array);//["World", "World", index: 0, input: "World Internet Conference"]
console.log(RegExp.);//World
console.log(reg.lastIndex);//5, 刚好等于 array.index + array[0].length

隨著檢索繼續, array.index 的值將往後遞增, 也就是說, reg.lastIndex 的值也會同步往後遞增. 因此, 我們也可以透過反覆呼叫exec 方法來遍歷字串中所有的匹配文字. 直到exec 方法再也匹配不到文字時, 它將傳回null, 並把reg.lastIndex 屬性重設為0.

接著上述例子, 我們繼續執行程式碼, 看看上面說的對不對, 如下所示:

array = reg.exec(string);
console.log(array);//["Internet", "Internet", index: 6, input: "World Internet Conference"]
console.log(reg.lastIndex);//14

array = reg.exec(string);
console.log(array);//["Conference", "Conference", index: 15, input: "World Internet Conference"]
console.log(reg.lastIndex);//25

array = reg.exec(string);
console.log(array);//null
console.log(reg.lastIndex);//0

以上程式碼中, 隨著重複呼叫 exec 方法, reg.lastIndex 屬性最終被重設為 0.

問題回顧

在test 方法的講解中, 我們留下了一個問題. 如果正則表達式帶有全局標誌g, 以上test 方法的執行結果將受reg.lastIndex影響, 不僅如此, exec 方法也一樣. 由於reg.lastIndex的值並不總是為零, 並且它決定了下次匹配開始的位置, 如果在一個字符串中完成了一次匹配之後要開始檢索新的字符串, 那就必須要手動地把lastIndex 屬性重置為0. 避免以下這種錯誤:

var reg = /[0-9]+/g,
    str1 = "123abc",
    str2 = "123456";
reg.exec(str1);
console.log(reg.lastIndex);//3
var array = reg.exec(str2);
console.log(array);//["456", index: 3, input: "123456"]

以上程式碼, 正確執行結果應該是 "123456", 因此建議在第二次執行 exec 方法前, 增加一句 "reg.lastIndex = 0;".

若 reg 不包含全域標示"g", 則 exec 方法的執行結果(array)將與 string.match(reg) 方法執行結果完全相同.

該片段來自 正規表示式前端使用手冊 | louis blog 有幫助的話請按讚吧~

巴扎黑

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板