RegExp.prototype[Symbol.replace]()

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

[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"

語法

js
regexp[Symbol.replace](str, replacement)

引數

str

一個作為替換目標的 String

replacement

可以是字串或函式。

  • 如果是一個字串,它將替換當前正則表示式匹配到的子字串。支援一些特殊的替換模式;請參閱 String.prototype.replace“將字串指定為替換內容” 部分。
  • 如果是一個函式,它將為每一次匹配呼叫,並使用其返回值作為替換文字。傳遞給該函式的引數在 String.prototype.replace“將函式指定為替換內容” 部分進行了描述。

返回值

一個新的字串,其中一個、一些或所有模式匹配項都被指定的替換內容替換。

描述

如果 pattern 引數是一個 RegExp 物件,則 String.prototype.replace()String.prototype.replaceAll() 會在內部呼叫此方法。例如,以下兩個示例返回相同的結果。

js
"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() 可能會返回不同的結果。

js
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 之後的所有出現項,但會失敗。

js
console.log("aa-a".replace(/a/gy, "b")); // "bb-a"

如果當前匹配是一個空字串,lastIndex 仍然會被推進——如果正則表示式是 Unicode 感知的,它將前進一個 Unicode 碼點;否則,它將前進一個 UTF-16 碼單元。

js
console.log("😄".replace(/(?:)/g, " ")); // " \ud83d \ude04 "
console.log("😄".replace(/(?:)/gu, " ")); // " 😄 "

此方法用於自定義 RegExp 子類中的替換行為。

示例

直接呼叫

此方法幾乎可以與 String.prototype.replace() 以相同的方式使用,除了 this 不同以及引數順序不同。

js
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]() 方法來修改預設行為。

js
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%

瀏覽器相容性

另見