如何在JavaScript中替换所有出现的字符串?
如何在JavaScript中替换所有出现的字符串?
给定一个字符串:
s = "Test abc test test abc test test test abc test test abc";
似乎只能删除上面字符串中第一次出现的abc
:
s = s.replace('abc', '');
我该如何替换所有出现的它?
为了完整起见,我考虑应该使用哪种方法来完成这个任务。基本上,根据本页面上其他答案的建议,有两种方法可以做到这一点。
注意:通常不建议在JavaScript中扩展内置原型。我仅提供作为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 }
我们可以在 String.prototype.replaceAll
的实现中调用 escapeRegExp
,但我不确定这会对性能产生多大影响(甚至对于不需要转义的字符串,比如所有的字母数字字符串)。
截至2020年8月:现代浏览器已经支持ECMAScript 2021语言规范定义的String.replaceAll()
方法。
对于旧版/传统浏览器:
function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\]/g, '\$&'); // $& means the whole matched string } function replaceAll(str, find, replace) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); }
这是答案的演变过程:
str = str.replace(/abc/g, '');
回应评论“如果'abc'作为变量传递怎么办?”:
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); }