先追這段程式
用 /^[a-z]+$/g 測 markup 兩次,重設 lastIndex 後再測。文字沒有變,regex 的狀態卻已不同。
const pattern=/^[a-z]+$/g;const results=[];
results.push(pattern.test('markup'));results.push(pattern.test('markup'));
pattern.lastIndex=0;results.push(pattern.test('markup'));
console.log(JSON.stringify(results));
[true,false,true]| 測試 | 真假結果 | lastIndex afterward |
|---|---|---|
| first markup | true | 6 |
| second markup | false | 0 |
| 重設後再測 markup | true | 6 |
結果為何如此
全域 regex 從 lastIndex 開始,成功後會更新。第二次由 6 開始,配合 ^ 起點要求便失敗,並重設為零。這種固定整段文字驗證可不用 g,避免帶狀態。y 也使用 lastIndex,但搜尋規則另有不同。
比較另一種寫法
本例全域模式不適合反覆無狀態驗證。修正為非全域後,同一有效字串兩次都通過;大寫邊界仍不符這個模式。
const pattern=/^[a-z]+$/;console.log(JSON.stringify([pattern.test('markup'),pattern.test('markup'),pattern.test('Markup')]));
[true,true,false]試清邊界
lastIndex=0 會否改變模式容許的字元?
查看參考答案
不會,只改開始位置。模式仍要求一個或以上小寫 ASCII 字母,沒有其他字元。
const pattern=/^[a-z]+$/g;const trace=[];for(const value of ['markup','markup','']){trace.push({value,ok:pattern.test(value),lastIndex:pattern.lastIndex});}
console.log(JSON.stringify(trace));
[{"value":"markup","ok":true,"lastIndex":6},{"value":"markup","ok":false,"lastIndex":0},{"value":"","ok":false,"lastIndex":0}]