问答中心分类: STRING如何替换 JavaScript 中所有出现的字符串?
0
mostafa elmadany 提问 1月 前

给定一个字符串:

s = "Test abc test test abc test test test abc test test abc";

这似乎只删除了第一次出现的abc在上面的字符串中:

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

我该如何更换全部发生的事吗?

reinierpost 回复 1月 前

当替换所有出现的abaababaca,你期待什么结果?caba?abca?cca?

reinierpost 回复 1月 前

String.prototype.replaceAll()现在是 ECMAScript 的标准部分tc39.es/ecma262/#sec-string.prototype.replaceall,记录在developer.mozilla.org/docs/Web/JavaScript/Reference/…并在 Safari 13.1、Firefox 77 和 Chrome Dev/Canary 中发布,并将在 Chrome 85 中发布。来自文档:“如果搜索值是一个字符串,替换所有出现的搜索值(仿佛.split(searchValue).join(replaceValue)或已使用全局和正确转义的正则表达式)。如果搜索值是一个非全局正则表达式,抛出异常”

reinierpost 回复 1月 前

使用正则表达式而不是字符串,应该看起来像str.replace(/abc/g, '');所以 g 得到所有匹配项。

29 Answers
0
Sean Bright 回答 1月 前

截至 2020 年 8 月: 现代浏览器有支持为了String.replaceAll()方法由 ECMAScript 2021 语言规范定义。

对于旧版/旧版浏览器:

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, '');

作为回应点击点赞的评论,你可以更简化它:

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);
}
MMMahdy-PAPION 回复 1月 前

escapeRegExp]}是额外的(不必转义)。最好是这样:.replace(/[.^$*+?()[{|\\]/g, "\\$&")

YipYip 回复 1月 前

您还需要转义替换字符串(考虑如何escapeRegExp用途$&在特殊行为的替换字符串中)。最后更改replace在最后一个代码块中replace.replace(/\$/g, '$$$$').看stackoverflow.com/a/6969486/2730641测试用例:replaceAll('abc def abc', 'abc', '$&@%#!') // Censor 'abc'

0
Cory Gross 回答 1月 前

为了完整起见,我开始考虑应该使用哪种方法来做到这一点。正如本页其他答案所建议的,基本上有两种方法可以做到这一点。
笔记:一般来说,一般不推荐在 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 机器上,基于正则表达式的实现是最快的, 与split 和 join 实现慢了 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但是,我不确定这会在多大程度上影响性能(甚至可能对于不需要转义的字符串,如所有字母数字字符串)。

MMMahdy-PAPION 回复 1月 前

2021年String.prototype.replaceAll()原生存在。所以这个实现应该在使用前先检查一下。

Sunil Garg 回复 1月 前

m使用nestjs,所以打字稿显示replaceAll不是String原型的方法的错误,有什么解决方案吗?

0
Adam A 回答 1月 前

使用正则表达式与g标志集将替换所有:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

也见这里

0
jesal 回答 1月 前

这是一个基于接受的答案的字符串原型函数:

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/

0
Elias Van Ootegem 回答 1月 前

更新:
更新有点晚了,但是因为我刚刚偶然发现了这个问题,并注意到我之前的答案不是我满意的答案。由于问题涉及替换单个单词,因此令人难以置信的是没有人想到使用单词边界(\b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

这是一个简单的正则表达式,可以避免在大多数情况下替换部分单词。然而,一个破折号-仍然被认为是一个单词边界。所以在这种情况下可以使用条件来避免替换字符串,如cool-cat

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

基本上,这个问题与这里的问题相同:Javascript 将“'”替换为“''”
@Mike,检查我在那里给出的答案……正则表达式不是替换多次出现的subsrting的唯一方法,远非如此。想灵活,想分裂!

var newText = "the cat looks like a cat".split('cat').join('dog');

或者,为了防止替换单词部分 – 批准的答案也会这样做!你可以使用正则表达式来解决这个问题,我承认,这些正则表达式有点复杂,结果也慢了一点:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

输出与接受的答案相同,但是,使用/cat/g此字符串上的表达式:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ??

糟糕,这可能不是您想要的。那是什么?恕我直言,一个仅有条件地替换“猫”的正则表达式。 (即不是单词的一部分),如下所示:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

我的猜测是,这可以满足您的需求。当然,它不是完全证明,但它应该足以让你开始。我建议在这些页面上阅读更多内容。这将有助于完善此表达式以满足您的特定需求。
http://www.javascriptkit.com/jsref/regexp.shtml
http://www.regular-expressions.info

最后补充:
鉴于这个问题仍然有很多观点,我想我可以添加一个例子.replace与回调函数一起使用。在这种情况下,它大大简化了表达式提供更大的灵活性,例如用正确的大写替换或同时替换两者catcats一气呵成:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar