試一試
const regex = /fo+/g;
const str = "table football, foosball";
let array;
while ((array = regex.exec(str)) !== null) {
console.log(`Found ${array[0]}. Next starts at ${regex.lastIndex}.`);
// Expected output: "Found foo. Next starts at 9."
// Expected output: "Found foo. Next starts at 19."
}
語法
exec(str)
引數
返回值
如果匹配失敗,exec() 方法返回 null,並將正則表示式的 lastIndex 設定為 0。
如果匹配成功,exec() 方法返回一個數組,並更新正則表示式物件的 lastIndex 屬性。返回的陣列將匹配的文字作為第一個元素,然後為匹配文字的每個捕獲組提供一個元素。陣列還具有以下附加屬性:
index-
匹配在字串中的 0 索引。
input-
用於匹配的原始字串。
groups-
一個
null-prototype 物件,包含命名捕獲組,其鍵是名稱,值是捕獲組,如果沒有定義命名捕獲組,則值為undefined。有關更多資訊,請參閱 捕獲組。 indices可選-
僅當設定了
d標誌時,才會出現此屬性。它是一個數組,其中每個條目代表一個子字串匹配的邊界。此陣列中每個元素的索引對應於exec()返回的陣列中相應子字串匹配的索引。換句話說,第一個indices條目代表整個匹配,第二個indices條目代表第一個捕獲組,依此類推。每個條目本身是一個包含兩個元素的陣列,第一個數字代表匹配的開始索引,第二個數字代表其結束索引。indices陣列還額外有一個groups屬性,其中包含所有命名捕獲組的null-prototype 物件。鍵是捕獲組的名稱,每個值是一個包含兩個元素的陣列,第一個數字是開始索引,第二個數字是捕獲組的結束索引。如果正則表示式不包含任何命名捕獲組,則groups為undefined。
描述
當設定了 全域性或 粘性 標誌(例如,/foo/g 或 /foo/y)時,JavaScript RegExp 物件是有狀態的。它們會儲存上一次匹配的 lastIndex。透過內部使用此屬性,exec() 可以用於迭代字串中的多個匹配(帶有捕獲組),而不是像 String.prototype.match() 那樣只獲取匹配的字串。
使用 exec() 時,如果設定了粘性標誌,全域性標誌將不起作用——匹配始終是粘性的。
exec() 是正則表示式的原生方法。許多其他正則表示式方法在內部呼叫 exec() — 包括字串方法呼叫的那些,例如 [Symbol.replace]()。雖然 exec() 本身功能強大(並且效率最高),但它通常不能最清晰地表達意圖。
- 如果你只關心正則表示式是否匹配一個字串,而不關心實際匹配了什麼,請改用
RegExp.prototype.test()。 - 如果你正在查詢全域性正則表示式的所有匹配項,並且不關心捕獲組等資訊,請改用
String.prototype.match()。此外,String.prototype.matchAll()可以透過允許你迭代匹配項來簡化匹配字串的多個部分(帶有捕獲組)。 - 如果你執行匹配是為了在字串中找到其索引位置,請改用
String.prototype.search()方法。
exec() 對於上面任何方法都難以實現的複雜操作很有用,通常在你需要手動調整 lastIndex 時。(String.prototype.matchAll() 會複製正則表示式,因此在迭代 matchAll 時更改 lastIndex 不會影響迭代。) 其中一個例子請參閱 重置 lastIndex。
示例
使用 exec()
考慮以下示例
// Match "quick brown" followed by "jumps", ignoring characters in between
// Remember "brown" and "jumps"
// Ignore case
const re = /quick\s(?<color>brown).+?(jumps)/dgi;
const result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog");
下表顯示了執行此指令碼後的 result 狀態
| 屬性 | 值 |
|---|---|
[0] |
"Quick Brown Fox Jumps" |
[1] |
"Brown" |
[2] |
"Jumps" |
index |
4 |
indices |
[[4, 25], [10, 15], [20, 25]]groups: { color: [10, 15 ]} |
input |
"The Quick Brown Fox Jumps Over The Lazy Dog" |
groups |
{ color: "Brown" } |
此外,re.lastIndex 將被設定為 25,因為這個正則表示式是全域性的。
查詢連續匹配項
如果你的正則表示式使用了 g 標誌,你可以多次使用 exec() 方法在同一個字串中查詢連續的匹配項。這樣做時,搜尋將從正則表示式的 lastIndex 屬性指定的 str 子字串開始(test() 也會推進 lastIndex 屬性)。請注意,在搜尋不同字串時,lastIndex 屬性不會被重置,它將從其當前 lastIndex 開始搜尋。
例如,假設你有以下指令碼
const myRe = /ab*/g;
const str = "abbcdefabh";
let myArray;
while ((myArray = myRe.exec(str)) !== null) {
let msg = `Found ${myArray[0]}. `;
msg += `Next match starts at ${myRe.lastIndex}`;
console.log(msg);
}
此指令碼顯示以下文字
Found abb. Next match starts at 3 Found ab. Next match starts at 9
警告: 有許多陷阱可能導致這種情況變成無限迴圈!
- 不要將正則表示式字面量(或
RegExp建構函式)放在while條件內 — 它將在每次迭代時重新建立正則表示式並重置lastIndex。 - 確保設定了 全域性 (
g) 標誌,否則lastIndex將永遠不會被推進。 - 如果正則表示式可能匹配零長度字元(例如,
/^/gm),請每次手動增加其lastIndex以避免停留在同一位置。
你通常可以用 String.prototype.matchAll() 替換此類程式碼,使其更不容易出錯。
使用 exec() 和 RegExp 字面量
你也可以在不顯式建立 RegExp 物件的情況下使用 exec()
const matches = /(hello \S+)/.exec("This is a hello world!");
console.log(matches[1]);
這將記錄一條包含 'hello world!' 的訊息。
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-regexp.prototype.exec |
瀏覽器相容性
載入中…