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