String.prototype.replace()
String
值的 replace()
方法返回一个新字符串,其中 pattern
的一个、部分或全部匹配项被 replacement
替换。pattern
可以是字符串或 RegExp
,replacement
可以是字符串或每次匹配调用的函数。如果 pattern
是字符串,则仅替换第一次出现的位置。原始字符串保持不变。
¥The replace()
method of String
values returns a new string with one, some, or all matches of a pattern
replaced by a replacement
. The pattern
can be a string or a RegExp
, and the replacement
can be a string or a function called for each match. If pattern
is a string, only the first occurrence will be replaced. The original string is left unchanged.
Try it
语法
参数
¥Parameters
pattern
-
可以是字符串或具有
Symbol.replace
方法的对象 - 典型示例是 正则表达式。任何不具有Symbol.replace
方法的值都将被强制转换为字符串。 replacement
-
: 可以是字符串或函数。
- 如果是字符串,则会替换
pattern
匹配的子字符串。支持多种特殊替换模式;请参阅下面的 指定字符串作为替换 部分。 - 如果它是一个函数,它将在每次匹配时调用它,并将其返回值用作替换文本。下面的 指定一个函数作为替换 部分描述了提供给该函数的参数。
- 如果是字符串,则会替换
返回值
描述
¥Description
此方法不会改变它所调用的字符串值。它返回一个新字符串。
¥This method does not mutate the string value it's called on. It returns a new string.
字符串模式只会被替换一次。要执行全局搜索和替换,请使用带有 g
标志的正则表达式,或改用 replaceAll()
。
¥A string pattern will only be replaced once. To perform a global search and replace, use a regular expression with the g
flag, or use replaceAll()
instead.
如果 pattern
是具有 Symbol.replace
方法的对象(包括 RegExp
对象),则使用目标字符串和 replacement
作为参数来调用该方法。它的返回值成为 replace()
的返回值。在这种情况下,replace()
的行为完全由 [Symbol.replace]()
方法编码 - 例如,下面描述中提到的 "捕获组" 实际上是 RegExp.prototype[Symbol.replace]()
提供的功能。
¥If pattern
is an object with a Symbol.replace
method (including RegExp
objects), that method is called with the target string and replacement
as arguments. Its return value becomes the return value of replace()
. In this case the behavior of replace()
is entirely encoded by the [Symbol.replace]()
method — for example, any mention of "capturing groups" in the description below is actually functionality provided by RegExp.prototype[Symbol.replace]()
.
如果 pattern
是空字符串,则替换内容将添加到字符串的开头。
¥If the pattern
is an empty string, the replacement is prepended to the start of the string.
"xxx".replace("", "_"); // "_xxx"
带有 g
标志的正则表达式是 replace()
替换多次的唯一情况。有关正则表达式属性(尤其是 sticky 标志)如何与 replace()
交互的更多信息,请参阅 RegExp.prototype[Symbol.replace]()
。
¥A regexp with the g
flag is the only case where replace()
replaces more than once. For more information about how regex properties (especially the sticky flag) interact with replace()
, see RegExp.prototype[Symbol.replace]()
.
指定字符串作为替换
¥Specifying a string as the replacement
替换字符串可以包含以下特殊替换模式:
¥The replacement string can include the following special replacement patterns:
图案 | 刀片 |
---|---|
$$ |
插入 "$" 。 |
$& |
插入匹配的子字符串。 |
`$`` | 插入匹配子字符串之前的字符串部分。 |
$' |
插入匹配子字符串后面的字符串部分。 |
$n |
插入第 n 个(1 索引)捕获组,其中 n 是小于 100 的正整数。 |
$<Name> |
插入命名的捕获组,其中 Name 是组名称。 |
仅当 pattern
参数是 RegExp
对象时,$n
和 $<Name>
才可用。如果 pattern
是字符串,或者正则表达式中不存在相应的捕获组,则该模式将被替换为文字。如果该组存在但不匹配(因为它是析取的一部分),它将被替换为空字符串。
¥$n
and $<Name>
are only available if the pattern
argument is a RegExp
object. If the pattern
is a string, or if the corresponding capturing group isn't present in the regex, then the pattern will be replaced as a literal. If the group is present but isn't matched (because it's part of a disjunction), it will be replaced with an empty string.
"foo".replace(/(f)/, "$2");
// "$2oo"; the regex doesn't have the second group
"foo".replace("f", "$1");
// "$1oo"; the pattern is a string, so it doesn't have any groups
"foo".replace(/(f)|(g)/, "$2");
// "oo"; the second group exists but isn't matched
指定一个函数作为替换
¥Specifying a function as the replacement
你可以指定一个函数作为第二个参数。在这种情况下,将在执行匹配后调用该函数。函数的结果(返回值)将用作替换字符串。
¥You can specify a function as the second parameter. In this case, the function will be invoked after the match has been performed. The function's result (return value) will be used as the replacement string.
注意:上述特殊替换模式不适用于从 Replacer 函数返回的字符串。
¥Note: The above-mentioned special replacement patterns do not apply for strings returned from the replacer function.
该函数具有以下签名:
¥The function has the following signature:
function replacer(match, p1, p2, /* …, */ pN, offset, string, groups) {
return replacement;
}
该函数的参数如下:
¥The arguments to the function are as follows:
match
-
匹配的子串。(对应上面的
$&
。) p1, p2, …, pN
-
捕获组(包括命名捕获组)找到的第
n
个字符串,前提是replace()
的第一个参数是RegExp
对象。(对应上面的$1
、$2
等。)例如,如果pattern
是/(\a+)(\b+)/
,则p1
是\a+
的匹配,p2
是\b+
的匹配。如果该组是析取的一部分(例如"abc".replace(/(a)|(b)/, replacer)
),则不匹配的替代项将是undefined
。 offset
-
所检查的整个字符串中匹配子字符串的偏移量。例如,如果整个字符串是
'abcd'
,匹配的子字符串是'bc'
,则该参数将为1
。 string
-
正在检查整个字符串。
groups
-
一个对象,其键是使用的组名称,其值是匹配部分(如果不匹配则为
undefined
)。仅当pattern
包含至少一个命名捕获组时才存在。
参数的确切数量取决于第一个参数是否是 RegExp
对象 - 如果是,则它有多少个捕获组。
¥The exact number of arguments depends on whether the first argument is a RegExp
object — and, if so, how many capture groups it has.
以下示例将 newString
设置为 'abc - 12345 - #$*%'
:
¥The following example will set newString
to 'abc - 12345 - #$*%'
:
function replacer(match, p1, p2, p3, offset, string) {
// p1 is non-digits, p2 digits, and p3 non-alphanumerics
return [p1, p2, p3].join(" - ");
}
const newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString); // abc - 12345 - #$*%
如果第一个参数中的正则表达式是全局的,则对于要替换的每个完整匹配项,该函数将被多次调用。
¥The function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global.
示例
在 replace()中定义正则表达式
¥Defining the regular expression in replace()
在以下示例中,正则表达式在 replace()
中定义并包含忽略大小写标志。
¥In the following example, the regular expression is defined in replace()
and includes the ignore case flag.
const str = "Twas the night before Xmas...";
const newstr = str.replace(/xmas/i, "Christmas");
console.log(newstr); // Twas the night before Christmas...
这会记录 'Twas the night before Christmas...'
。
¥This logs 'Twas the night before Christmas...'
.
注意:有关正则表达式的更多说明,请参阅 正则表达式指南。
¥Note: See the regular expression guide for more explanations about regular expressions.
将全局和 ignoreCase 标志与 replace()一起使用
¥Using the global and ignoreCase flags with replace()
全局替换只能使用正则表达式来完成。在以下示例中,正则表达式包括 全局和忽略大小写标志,它允许 replace()
将字符串中每次出现的 'apples'
替换为 'oranges'
。
¥Global replace can only be done with a regular expression. In the following example, the regular expression includes the global and ignore case flags which permits replace()
to replace each occurrence of 'apples'
in the string with 'oranges'
.
const re = /apples/gi;
const str = "Apples are round, and apples are juicy.";
const newstr = str.replace(re, "oranges");
console.log(newstr); // oranges are round, and oranges are juicy.
这会记录 'oranges are round, and oranges are juicy'
。
¥This logs 'oranges are round, and oranges are juicy'
.
交换字符串中的单词
¥Switching words in a string
以下脚本切换字符串中的单词。对于替换文本,脚本使用 捕获组 以及 $1
和 $2
替换模式。
¥The following script switches the words in the string. For the replacement text, the script uses capturing groups and the $1
and $2
replacement patterns.
const re = /(\w+)\s(\w+)/;
const str = "Maria Cruz";
const newstr = str.replace(re, "$2, $1");
console.log(newstr); // Cruz, Maria
这会记录 'Cruz, Maria'
。
¥This logs 'Cruz, Maria'
.
使用修改匹配字符的内联函数
¥Using an inline function that modifies the matched characters
在此示例中,字符串中所有出现的大写字母都将转换为小写,并在匹配位置之前插入连字符。这里重要的是,在将匹配的物品作为替换件返还之前,需要对匹配的物品进行额外的操作。
¥In this example, all occurrences of capital letters in the string are converted to lower case, and a hyphen is inserted just before the match location. The important thing here is that additional operations are needed on the matched item before it is given back as a replacement.
替换函数接受匹配的代码片段作为其参数,并使用它来转换大小写并在返回之前连接连字符。
¥The replacement function accepts the matched snippet as its parameter, and uses it to transform the case and concatenate the hyphen before returning.
function styleHyphenFormat(propertyName) {
function upperToHyphenLower(match, offset, string) {
return (offset > 0 ? "-" : "") + match.toLowerCase();
}
return propertyName.replace(/[A-Z]/g, upperToHyphenLower);
}
给定 styleHyphenFormat('borderTop')
,返回 'border-top'
。
¥Given styleHyphenFormat('borderTop')
, this returns 'border-top'
.
因为我们想要在最终替换之前进一步转换比赛结果,所以我们必须使用一个函数。这迫使在 toLowerCase()
方法之前对匹配进行评估。如果我们尝试使用不带函数的匹配来执行此操作,则 toLowerCase()
将不起作用。
¥Because we want to further transform the result of the match before the final substitution is made, we must use a function. This forces the evaluation of the match prior to the toLowerCase()
method. If we had tried to do this using the match without a function, the toLowerCase()
would have no effect.
// Won't work
const newString = propertyName.replace(/[A-Z]/g, "-" + "$&".toLowerCase());
这是因为在使用字符作为模式之前,'$&'.toLowerCase()
首先会被评估为字符串文字(导致相同的 '$&'
)。
¥This is because '$&'.toLowerCase()
would first be evaluated as a string literal (resulting in the same '$&'
) before using the characters as a pattern.
将华氏度替换为相应的摄氏度
¥Replacing a Fahrenheit degree with its Celsius equivalent
以下示例将华氏度替换为其等效的摄氏度。华氏度应该是以 "F"
结尾的数字。该函数返回以 "C"
结尾的摄氏度。例如,如果输入数字为 "212F"
,则函数返回 "100C"
。如果数字是 "0F"
,则该函数返回 "-17.77777777777778C"
。
¥The following example replaces a Fahrenheit degree with its equivalent Celsius degree. The Fahrenheit degree should be a number ending with "F"
. The function returns the Celsius number ending with "C"
. For example, if the input number is "212F"
, the function returns "100C"
. If the number is "0F"
, the function returns "-17.77777777777778C"
.
正则表达式 test
检查是否有任何以 F
结尾的数字。该函数可通过其第二个参数 p1
访问华氏度数。该函数根据字符串中传递给 f2c()
函数的华氏度数设置摄氏度。然后 f2c()
返回摄氏度。该函数近似于 Perl 的 s///e
标志。
¥The regular expression test
checks for any number that ends with F
. The number of Fahrenheit degrees is accessible to the function through its second parameter, p1
. The function sets the Celsius number based on the number of Fahrenheit degrees passed in a string to the f2c()
function. f2c()
then returns the Celsius number. This function approximates Perl's s///e
flag.
function f2c(x) {
function convert(str, p1, offset, s) {
return `${((p1 - 32) * 5) / 9}C`;
}
const s = String(x);
const test = /(-?\d+(?:\.\d*)?)F\b/g;
return s.replace(test, convert);
}
制作通用替代品
¥Making a generic replacer
假设我们要创建一个替换器,将偏移量数据附加到每个匹配的字符串。因为替换函数已经接收了 offset
参数,所以如果正则表达式是静态已知的,那么这将是微不足道的。
¥Suppose we want to create a replacer that appends the offset data to every matched string. Because the replacer function already receives the offset
parameter, it will be trivial if the regex is statically known.
"abcd".replace(/(bc)/, (match, p1, offset) => `${match} (${offset}) `);
// "abc (1) d"
然而,如果我们希望它能够与任何正则表达式模式一起使用,那么这个替换器将很难概括。替换器是可变的 - 它接收的参数数量取决于存在的捕获组的数量。我们可以使用 其余参数,但它也会将 offset
、string
等收集到数组中。事实上,groups
可能会或可能不会被传递取决于正则表达式的身份,这也使得很难一般地知道哪个参数对应于 offset
。
¥However, this replacer would be hard to generalize if we want it to work with any regex pattern. The replacer is variadic — the number of arguments it receives depends on the number of capturing groups present. We can use rest parameters, but it would also collect offset
, string
, etc. into the array. The fact that groups
may or may not be passed depending on the identity of the regex would also make it hard to generically know which argument corresponds to the offset
.
function addOffset(match, ...args) {
const offset = args.at(-2);
return `${match} (${offset}) `;
}
console.log("abcd".replace(/(bc)/, addOffset)); // "abc (1) d"
console.log("abcd".replace(/(?<group>bc)/, addOffset)); // "abc (abcd) d"
当正则表达式包含命名组时,上面的 addOffset
示例不起作用,因为在这种情况下,args.at(-2)
将是 string
而不是 offset
。
¥The addOffset
example above doesn't work when the regex contains a named group, because in this case args.at(-2)
would be the string
instead of the offset
.
相反,你需要根据类型提取最后几个参数,因为 groups
是一个对象,而 string
是一个字符串。
¥Instead, you need to extract the last few arguments based on type, because groups
is an object while string
is a string.
function addOffset(match, ...args) {
const hasNamedGroups = typeof args.at(-1) === "object";
const offset = hasNamedGroups ? args.at(-3) : args.at(-2);
return `${match} (${offset}) `;
}
console.log("abcd".replace(/(bc)/, addOffset)); // "abc (1) d"
console.log("abcd".replace(/(?<group>bc)/, addOffset)); // "abc (1) d"
规范
Specification |
---|
ECMAScript Language Specification # sec-string.prototype.replace |
浏览器兼容性
BCD tables only load in the browser