RegExp.prototype[Symbol.replace]()
RegExp
实例的 [Symbol.replace]()
方法指定当正则表达式作为模式传入时 String.prototype.replace()
和 String.prototype.replaceAll()
应如何表现。
¥The [Symbol.replace]()
method of RegExp
instances specifies how String.prototype.replace()
and String.prototype.replaceAll()
should behave when the regular expression is passed in as the pattern.
Try it
语法
参数
¥Parameters
str
-
作为替换对象的
String
。 replacement
-
: 可以是字符串或函数。
- 如果是字符串,它将替换当前正则表达式匹配的子字符串。支持多种特殊替换模式;请参阅
String.prototype.replace
的 指定字符串作为替换 部分。 - 如果它是一个函数,它将在每次匹配时调用它,并将返回值用作替换文本。提供给该函数的参数在
String.prototype.replace
的 指定一个函数作为替换 部分中描述。
- 如果是字符串,它将替换当前正则表达式匹配的子字符串。支持多种特殊替换模式;请参阅
返回值
描述
¥Description
如果 pattern
参数是 RegExp
对象,则在 String.prototype.replace()
和 String.prototype.replaceAll()
内部调用此方法。例如,以下两个示例返回相同的结果。
¥This method is called internally in String.prototype.replace()
and String.prototype.replaceAll()
if the pattern
argument is a RegExp
object. For example, the following two examples return the same result.
"abc".replace(/a/, "A");
/a/[Symbol.replace]("abc", "A");
如果正则表达式是全局的(带有 g
标志),则将重复调用正则表达式的 exec()
方法,直到 exec()
返回 null
。否则,exec()
只会被调用一次。对于每个 exec()
结果,将根据 String.prototype.replace()
中的描述准备替换。
¥If the regex is global (with the g
flag), the regex's exec()
method will be repeatedly called until exec()
returns null
. Otherwise, exec()
would only be called once. For each exec()
result, the substitution will be prepared based on the description in String.prototype.replace()
.
因为 [Symbol.replace]()
会一直调用 exec()
直到返回 null
,而当最后一次匹配失败时,exec()
会自动将正则表达式的 lastIndex
重置为 0,所以 [Symbol.replace]()
在退出时通常不会产生副作用。但是,当正则表达式为 sticky 但不是全局时,lastIndex
不会被重置。在这种情况下,每次调用 replace()
可能会返回不同的结果。
¥Because [Symbol.replace]()
would keep calling exec()
until it returns null
, and exec()
would automatically reset the regex's lastIndex
to 0 when the last match fails, [Symbol.replace]()
would typically not have side effects when it exits. However, when the regex is sticky but not global, lastIndex
would not be reset. In this case, each call to replace()
may return a different result.
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
之外的任何匹配项。
¥When the regex is sticky and global, it would still perform sticky matches — i.e. it would fail to match any occurrences beyond the lastIndex
.
console.log("aa-a".replace(/a/gy, "b")); // "bb-a"
如果当前匹配是空字符串,则 lastIndex
仍会提前 - 如果正则表达式是 Unicode 感知,则它将提前一个 Unicode 代码点;否则,前进一个 UTF-16 代码单元。
¥If the current match is an empty string, the lastIndex
would still be advanced — if the regex is Unicode-aware, it would advance by one Unicode code point; otherwise, it advances by one UTF-16 code unit.
console.log("😄".replace(/(?:)/g, " ")); // " \ud83d \ude04 "
console.log("😄".replace(/(?:)/gu, " ")); // " 😄 "
此方法用于自定义 RegExp
子类中的替换行为。
¥This method exists for customizing replace behavior in RegExp
subclasses.
示例
直接致电
¥Direct call
该方法的使用方式与 String.prototype.replace()
几乎相同,只是 this
和参数顺序不同。
¥This method can be used in almost the same way as String.prototype.replace()
, except the different this
and the different arguments order.
const re = /-/g;
const str = "2016-01-01";
const newstr = re[Symbol.replace](str, ".");
console.log(newstr); // 2016.01.01
在子类中使用 [Symbol.replace]()
¥Using [Symbol.replace]()
in subclasses
RegExp
的子类可以重写 [Symbol.replace]()
方法来修改默认行为。
¥Subclasses of RegExp
can override the [Symbol.replace]()
method to modify the default behavior.
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
规范
Specification |
---|
ECMAScript Language Specification # sec-regexp.prototype-@@replace |
浏览器兼容性
BCD tables only load in the browser
也可以看看
¥See also
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