RegExp.prototype[Symbol.replace]()

基线 广泛可用

此功能已得到很好的确立,并且可以在许多设备和浏览器版本上运行。它自以下时间起在所有浏览器中都可用 2015 年 7 月.

[Symbol.replace]() 方法是 RegExp 实例的方法,它指定了当将正则表达式作为模式传递时,String.prototype.replace()String.prototype.replaceAll() 应如何执行。

试一试

语法

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 语言规范
# sec-regexp.prototype-%symbol.replace%

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅