RegExp.prototype[Symbol.replace]()
[Symbol.replace]() 方法是 RegExp 例項上的一種方法,它規定了當正則表示式被用作模式引數時,String.prototype.replace() 和 String.prototype.replaceAll() 的行為。
試一試
class RegExp1 extends RegExp {
[Symbol.replace](str) {
return RegExp.prototype[Symbol.replace].call(this, str, "#!@?");
}
}
console.log("football".replace(new RegExp1("foo")));
// Expected output: "#!@?tball"
語法
regexp[Symbol.replace](str, replacement)
引數
str-
一個作為替換目標的
String。 replacement-
可以是字串或函式。
- 如果是一個字串,它將替換當前正則表示式匹配到的子字串。支援一些特殊的替換模式;請參閱
String.prototype.replace的 “將字串指定為替換內容” 部分。 - 如果是一個函式,它將為每一次匹配呼叫,並使用其返回值作為替換文字。傳遞給該函式的引數在
String.prototype.replace的 “將函式指定為替換內容” 部分進行了描述。
- 如果是一個字串,它將替換當前正則表示式匹配到的子字串。支援一些特殊的替換模式;請參閱
返回值
一個新的字串,其中一個、一些或所有模式匹配項都被指定的替換內容替換。
描述
如果 pattern 引數是一個 RegExp 物件,則 String.prototype.replace() 和 String.prototype.replaceAll() 會在內部呼叫此方法。例如,以下兩個示例返回相同的結果。
"abc".replace(/a/, "A");
/a/[Symbol.replace]("abc", "A");
如果正則表示式是全域性的(帶有 g 標誌),則會反覆呼叫正則表示式的 exec() 方法,直到 exec() 返回 null。否則,exec() 只會被呼叫一次。對於每一次 exec() 的結果,都會根據 String.prototype.replace() 的描述來準備替換。
由於 [Symbol.replace]() 會持續呼叫 exec() 直到其返回 null,並且 exec() 在最後一次匹配失敗時會自動將正則表示式的 lastIndex 重置為 0,因此 [Symbol.replace]() 在退出時通常不會產生副作用。然而,當正則表示式是 粘性的 但非全域性的,lastIndex 不會被重置。在這種情況下,每次呼叫 replace() 可能會返回不同的結果。
const re = /a/y;
for (let i = 0; i < 5; i++) {
console.log("aaa".replace(re, "b"), re.lastIndex);
}
// baa 1
// aba 2
// aab 3
// aaa 0
// baa 1
當正則表示式是粘性且全域性的,它仍然會執行粘性匹配——即,它會嘗試匹配 lastIndex 之後的所有出現項,但會失敗。
console.log("aa-a".replace(/a/gy, "b")); // "bb-a"
如果當前匹配是一個空字串,lastIndex 仍然會被推進——如果正則表示式是 Unicode 感知的,它將前進一個 Unicode 碼點;否則,它將前進一個 UTF-16 碼單元。
console.log("😄".replace(/(?:)/g, " ")); // " \ud83d \ude04 "
console.log("😄".replace(/(?:)/gu, " ")); // " 😄 "
此方法用於自定義 RegExp 子類中的替換行為。
示例
直接呼叫
此方法幾乎可以與 String.prototype.replace() 以相同的方式使用,除了 this 不同以及引數順序不同。
const re = /-/g;
const str = "2016-01-01";
const newStr = re[Symbol.replace](str, ".");
console.log(newStr); // 2016.01.01
在子類中使用 [Symbol.replace]()
RegExp 的子類可以覆蓋 [Symbol.replace]() 方法來修改預設行為。
class MyRegExp extends RegExp {
constructor(pattern, flags, count) {
super(pattern, flags);
this.count = count;
}
[Symbol.replace](str, replacement) {
// Perform [Symbol.replace]() `count` times.
let result = str;
for (let i = 0; i < this.count; i++) {
result = RegExp.prototype[Symbol.replace].call(this, result, replacement);
}
return result;
}
}
const re = new MyRegExp("\\d", "", 3);
const str = "01234567";
const newStr = str.replace(re, "#"); // String.prototype.replace calls re[Symbol.replace]().
console.log(newStr); // ###34567
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-regexp.prototype-%symbol.replace% |
瀏覽器相容性
載入中…
另見
core-js中RegExp.prototype[Symbol.replace]的 PolyfillString.prototype.replace()String.prototype.replaceAll()RegExp.prototype[Symbol.match]()RegExp.prototype[Symbol.matchAll]()RegExp.prototype[Symbol.search]()RegExp.prototype[Symbol.split]()RegExp.prototype.exec()RegExp.prototype.test()Symbol.replace