如何在JavaScript中替换所有出现的字符串?

我有这个字符串:

"Test abc test test abc test test test abc test test abc"

str = str.replace('abc', '');

似乎只删除abc上面字符串中的第一个出现。如何更换所有出现的内容?


为了完整起见,我开始考虑使用哪种方法来完成这项工作。根据本页其他答案的建议,基本上有两种方法可以做到这一点。

注意:通常,建议不要在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);
};

在效率方面我不太了解正则表达式如何在幕后工作,我倾向于倾向于分裂并在过去加入实现而不考虑性能。当我确实想知道哪个更有效率,以及在什么边缘时,我用它作为借口来找出答案。

在我的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实现中调用,但是,我不确定这会对性能产生多大影响(甚至可能对于不需要转义的字符串,例如所有字母数字字符串)。


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指南中介绍了这一点,它们提供了以下实用程序功能:

function escapeRegExp(str) {
    return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

因此,为了使上述replaceAll()功能更安全,如果您还包括以下内容,则可将其修改为以下内容escapeRegExp

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

添加评论

友情链接:蝴蝶教程