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

我有这个字符串:

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

正在做:

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

似乎只删除上面字符串中的abc第一次出现。

如何替换所有出现的内容?

答案

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 ,则可以将其修改为以下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);
};

在效率方面,对正则表达式的幕后工作一无所知,我过去倾向于倾向于拆分并加入实现,而没有考虑性能。当我确实想知道哪种效率更高,效率更高时,我以它为借口进行查找。

在我的 Chrome Windows 8 计算机上, 基于正则表达式的实现是最快的 ,而split and join 实现的速度要慢 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 ,但是,我不确定这会对性能产生多大的影响(甚至对于不需要转义的字符串(如所有字母数字字符串)也可能会影响性能)。

注意:不要在对性能有要求的代码中使用此代码。

作为简单文字字符串的正则表达式的替代方法,您可以使用

str = "Test abc test test abc test...".split("abc").join("");

一般模式是

str.split(search).join(replacement)

在某些情况下,这过去比使用replaceAll和正则表达式要快,但是在现代浏览器中,情况似乎不再如此。

基准: https : //jsperf.com/replace-all-vs-split-join

结论:如果您有性能至关重要的用例(例如,处理数百个字符串),请使用 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/

更新:

更新有点晚了,但是由于我偶然发现了这个问题,并且注意到我以前的回答不是我满意的答案。由于问题涉及替换单个单词,所以没有人想到使用单词边界( \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,请检查我在此处给出的答案... regexp 并不是替换 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" ??

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

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

与全局正则表达式匹配:

anotherString = someString.replace(/cat/g, 'dog');

要更换一次,请使用:

var res = str.replace('abc', "");

要多次更换,请使用:

var res = str.replace(/abc/g, "");

这些是最常见且易读的方法。

var str = "Test abc test test abc test test test abc test test abc"

方法 - 01:

str = str.replace(/abc/g, "replaced text");

方法 - 02:

str = str.split("abc").join("replaced text");

方法 03:

str = str.replace(new RegExp("abc", "g"), "replaced text");

方法 - 04:

while(str.includes("abc")){
    str = str.replace("abc", "replaced text");
}

输出:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
str = str.replace(/abc/g, '');

或者从这里尝试 replaceAll 函数:

有什么有用的 JavaScript 方法可以扩展内置对象?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

编辑:有关 replaceAll 可用性的说明

'replaceAll' 方法已添加到 String 的原型中。这意味着它将适用于所有字符串对象 / 文字。

例如

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'