我的 JavaScript 代码中有这个字符串:
"Test abc test test abc test test test abc test test abc"
正在做:
str = str.replace('abc', '');
似乎只删除了abc
上面字符串中第一次出现的。
我怎样才能替换它的所有出现?
我的 JavaScript 代码中有这个字符串:
"Test abc test test abc test test test abc test test abc"
正在做:
str = str.replace('abc', '');
似乎只删除了abc
上面字符串中第一次出现的。
我怎样才能替换它的所有出现?
截至 2020 年 8 月: 现代浏览器支持ECMAScript 2021 语言规范定义的String.replaceAll()
方法。
对于旧版/旧版浏览器:
str = str.replace(/abc/g, '');
回应评论:
var find = 'abc';
var re = new RegExp(find, 'g');
str = str.replace(re, '');
为了回应Click Upvote的评论,您可以进一步简化它:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
注意:正则表达式包含特殊(元)字符,因此在find
上面的函数中盲目传递参数而不对其进行预处理以转义这些字符是危险的。这在Mozilla 开发人员网络的JavaScript 正则表达式指南中有所介绍,其中提供了以下实用程序功能(自最初编写此答案以来已更改至少两次,因此请务必检查 MDN 站点以获取潜在更新):
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
因此,为了使上述replaceAll()
功能更安全,如果您还包含以下内容,则可以将其修改为以下内容escapeRegExp
:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
为了完整起见,我开始考虑应该使用哪种方法来执行此操作。正如本页其他答案所建议的那样,基本上有两种方法可以做到这一点。
注意:一般情况下,一般不推荐扩展 JavaScript 中的内置原型。我提供 String 原型的扩展只是为了说明的目的,展示了String
内置原型上假设标准方法的不同实现。
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
不太了解正则表达式在效率方面的幕后工作原理,过去我倾向于倾向于 split 和 join 实现而不考虑性能。当我确实想知道哪个更有效,以及在多大程度上更有效时,我用它作为找出答案的借口。
在我的 Chrome Windows 8 机器上,基于正则表达式的实现是最快的,拆分和连接的实现要慢 53%。这意味着正则表达式的速度是我使用的 lorem ipsum 输入的两倍。
查看这个基准测试,运行这两个实现。
正如@ThomasLeduc 和其他人在下面的评论中所指出的,如果search
包含某些在正则表达式中保留为特殊字符的字符,则基于正则表达式的实现可能会出现问题。该实现假定调用者将事先对字符串进行转义,或者仅传递正则表达式(MDN)中表中没有字符的字符串。
MDN 还提供了一个实现来转义我们的字符串。如果这也被标准化为RegExp.escape(str)
,那就太好了,但唉,它不存在:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
我们可以escapeRegExp
在我们的String.prototype.replaceAll
实现中调用,但是,我不确定这会在多大程度上影响性能(甚至对于不需要转义的字符串,如所有字母数字字符串)。
更新:在最流行的浏览器的最新版本中,您可以使用replaceAll
如下所示:
let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"
但是首先检查我可以使用或其他兼容性表,以确保您的目标浏览器首先添加了对它的支持。
对于 Node 和与旧/非当前浏览器的兼容性:
注意:不要在性能关键代码中使用以下解决方案。
作为简单文字字符串的正则表达式的替代方案,您可以使用
str = "Test abc test test abc test...".split("abc").join("");
一般模式是
str.split(search).join(replacement)
在某些情况下,这曾经比使用replaceAll
正则表达式更快,但在现代浏览器中似乎不再如此。
基准:https : //jsben.ch/TZYzj
结论:如果您有一个性能关键的用例(例如处理数百个字符串),请使用 Regexp 方法。但是对于大多数典型的用例来说,不必担心特殊字符是非常值得的。
使用带有g
标志集的正则表达式将替换所有:
someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"
这是基于接受的答案的字符串原型函数:
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find, 'g'), replace);
};
编辑
如果您的find
遗嘱包含特殊字符,那么您需要对它们进行转义:
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
小提琴:http : //jsfiddle.net/cdbzL/