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

给定一个字符串:

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

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

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

如何替换所有次出现?

4317100 次浏览

使用设置了g标志的正则表达式将替换所有:

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

参见这里

匹配一个全局正则表达式:

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

截至2020年8月:现代浏览器支持#0方法定义的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);}
str = str.replace(/abc/g, '');

或者尝试replaceAll方法,如这个答案中推荐的:

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

或:

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'

使用正则表达式:

str.replace(/abc/g, '');

在最流行的浏览器的最新版本中,您可以使用replaceAll如图所示:

let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");// `result` is "1 xyz 2 xyz 3"

但是首先检查我可以用或其他兼容性表,以确保您的目标浏览器首先添加了对它的支持。


对于Node.js和与旧/非当前浏览器的兼容性:

注意:不要在性能关键代码中使用以下解决方案。

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

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

一般的模式是

str.split(search).join(replacement)

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

基准:https://jsben.ch/TZYzj

结论:

如果您有一个性能关键的用例(例如,处理数百个字符串),请使用正则表达式方法。但对于大多数典型的用例,这很值得不必担心特殊字符。

我的实现,非常不言自明

function replaceAll(string, token, newtoken) {if(token!=newtoken)while(string.indexOf(token) > -1) {string = string.replace(token, newtoken);}return string;}

使用单词边界(\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中的“'”替换为“”

Regexp不是替换多次出现的子字符串的唯一方法,远非如此。想想灵活,想想拆分!

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" ??

哎呀,这可能不是你想要的。那是什么?IMHO,一个只有条件地替换'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"

我的猜测是,这满足了您的需求。当然,这不是万无一失的,但它应该足以让您开始。我建议您在这些页面上阅读更多内容。这将有助于完善此表达式以满足您的特定需求。


这是一个与回调函数一起使用的.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 requiredvar replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';if (char1 === ' ' && char2 === 's'){ // Replace plurals, toocat = replacement + 's';}else{ // Do not replace if dashes are matchedcat = 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

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

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/

我喜欢这个方法(看起来更干净):

text = text.replace(new RegExp("cat","g"), "dog");

循环它,直到数字出现为0,像这样:

function replaceAll(find, replace, str) {while (str.indexOf(find) > -1) {str = str.replace(find, replace);}return str;}

如果你想要查找的内容已经在字符串中,并且你没有正则转义器,你可以使用连接/拆分:

    function replaceMulti(haystack, needle, replacement){return haystack.split(needle).join(replacement);}
someString = 'the cat looks like a cat';console.log(replaceMulti(someString, 'cat', 'dog'));

为了完整起见,我开始考虑我应该使用哪种方法来做到这一点。基本上有两种方法可以做到这一点,正如本页上其他答案所建议的那样。

备注:一般来说,一般不建议扩展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);};

由于不太了解正则表达式在效率方面的幕后工作原理,我过去倾向于拆分并加入实现,而不考虑性能。当我确实想知道哪个更有效,以及效率提高了多少时,我会用它作为找出答案的借口。

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

var str = "ff ff f f a de def";str = str.replace(/f/g,'');alert(str);

http://jsfiddle.net/ANHR9/

要替换所有类型的字符,请尝试以下代码:

假设我们需要在我的字符串中发送"和\。然后我们将其转换为"和\to\。

所以这种方法将解决这个问题。

String.prototype.replaceAll = function (find, replace) {var str = this;return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);};
var message = $('#message').val();message = message.replaceAll('\\', '\\\\'); /*it will replace \ to \\ */message = message.replaceAll('"', '\\"');   /*it will replace " to \\"*/

我使用的是Ajax,我需要以JSON格式发送参数。然后我的方法如下所示:

 function sendMessage(source, messageID, toProfileID, userProfileID) {
if (validateTextBox()) {var message = $('#message').val();message = message.replaceAll('\\', '\\\\');message = message.replaceAll('"', '\\"');$.ajax({type: "POST",async: "false",contentType: "application/json; charset=utf-8",url: "services/WebService1.asmx/SendMessage",data: '{"source":"' + source + '","messageID":"' + messageID + '","toProfileID":"' + toProfileID + '","userProfileID":"' + userProfileID + '","message":"' + message + '"}',dataType: "json",success: function (data) {loadMessageAfterSend(toProfileID, userProfileID);$("#<%=PanelMessageDelete.ClientID%>").hide();$("#message").val("");$("#delMessageContainer").show();$("#msgPanel").show();},error: function (result) {alert("message sending failed");}});}else {alert("Please type message in message box.");$("#message").focus();
}}
String.prototype.replaceAll = function (find, replace) {var str = this;return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);};

试试这个:

String.prototype.replaceAll = function (sfind, sreplace) {var str = this;
while (str.indexOf(sfind) > -1) {str = str.replace(sfind, sreplace);}
return str;};

这是不使用正则表达式最快版本。

replaceAll = function(string, omit, place, prevstring) {if (prevstring && string === prevstring)return string;prevstring = string.replace(omit, place);return replaceAll(prevstring, omit, place, string)}

它几乎与拆分和连接方法一样快。

正如在这里的注释中指出的,如果您的omit变量包含place,这将不起作用,例如:replaceAll("string", "s", "ss"),因为它总是能够替换该单词的另一个出现。

在我的递归替换上还有另一个带有变体的jspef,它走得更快(http://jsperf.com/replace-all-vs-split-join/12)!

  • 2017年7月27日更新:看起来RegExp现在在最近发布的Chrome59中具有最快的性能。
while (str.indexOf('abc') !== -1){str = str.replace('abc', '');}

如果使用库是您的一种选择,那么您将获得库函数附带的测试和社区支持的好处。例如,string.js库有一个replace eAll()函数,它可以完成您想要的事情:

// Include a reference to the string.js library and call it (for example) S.str = S(str).replaceAll('abc', '').s;

如果您试图确保您正在寻找的字符串即使在替换后也不存在,则需要使用循环。

例如:

var str = 'test aabcbc';str = str.replace(/abc/g, '');

完成后,您仍将拥有“测试abc”!

解决这个问题的最简单的循环是:

var str = 'test aabcbc';while (str != str.replace(/abc/g, '')){str.replace(/abc/g, '');}

但是,每个循环运行两次替换。也许(有被否决的风险)可以组合成一种稍微更有效但可读性较差的形式:

var str = 'test aabcbc';while (str != (str = str.replace(/abc/g, ''))){}// alert(str); alerts 'test '!

这在查找重复字符串时特别有用。
例如,如果我们有'a,,, b'并且我们希望删除所有重复的逗号。
[在这种情况下,可以执行.替换(/,+/g,','), 但在某些时候正则表达式变得复杂且足够慢以循环。

function replaceAll(str, find, replace) {var i = str.indexOf(find);if (i > -1){str = str.replace(find, replace);i = i + replace.length;var st2 = str.substring(i);if(st2.indexOf(find) > -1){str = str.substring(0,i) + replaceAll(st2, find, replace);}}return str;}

只需添加/g

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

// Replace 'hello' string with /hello/g regular expression.document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/g表示全局

替换单引号:

function JavaScriptEncode(text){text = text.replace(/'/g,'&apos;')// More encode here if required
return text;}

我使用p来存储上一个递归替换的结果:

function replaceAll(s, m, r, p) {return s === p || r.contains(m) ? s : replaceAll(s.replace(m, r), m, r, s);}

它将替换字符串<的trong>的中的所有出现,直到可能:

replaceAll('abbbbb', 'ab', 'a') → 'abbbb' → 'abbb' → 'abb' → 'ab' → 'a'

为了避免无限循环,我检查替换r是否包含匹配m

replaceAll('abbbbb', 'a', 'ab') → 'abbbbb'

您可以简单地使用下面的方法

/*** Replace all the occerencess of $find by $replace in $originalString* @param  {originalString} input - Raw string.* @param  {find} input - Target key word or regex that need to be replaced.* @param  {replace} input - Replacement key word* @return {String}       Output string*/function replaceAll(originalString, find, replace) {return originalString.replace(new RegExp(find, 'g'), replace);};

以下功能适用于我:

String.prototype.replaceAllOccurence = function(str1, str2, ignore){return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);} ;

现在像这样调用函数:

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

只需将此代码复制并粘贴到浏览器控制台中即可。

这是带有原型的工作代码:

String.prototype.replaceAll = function(find, replace) {var str = this;return str.replace(new RegExp(find.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"), 'g'), replace);};
function replaceAll(str, find, replace) {var $r="";while($r!=str){$r = str;str = str.replace(find, replace);}return str;}

虽然人们已经提到了regex的使用,但如果你想替换文本而不管文本的大小写,有一个更好的方法。像大写或小写。使用以下语法:

// Consider the below exampleoriginalString.replace(/stringToBeReplaced/gi, '');
// The output will be all the occurrences removed irrespective of casing.

您可以参考详细的示例这里

假设您想将所有'abc'替换为'x':

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')console.log(some_str) //x def def lom x x def

我试图考虑一些比修改字符串原型更简单的事情。

这可以使用正则表达式和标志g来解决,这意味着在找到第一个匹配项后不要停止。真的,正则表达式是救命稻草!

function replaceAll(string, pattern, replacement) {return string.replace(new RegExp(pattern, "g"), replacement);}
// or if you want myString.replaceAll("abc", "");
String.prototype.replaceAll = function(pattern, replacement) {return this.replace(new RegExp(pattern, "g"), replacement);};

大多数人可能会这样做来编码URL。要编码URL,您不仅应该考虑空格,还应该使用encodeURI正确转换整个字符串。

encodeURI("http://www.google.com/a file with spaces.html")

以获得:

http://www.google.com/a%20file%20with%20spaces.html

javascript中使用RegExp可以为您完成这项工作。只需简单地执行以下代码,不要忘记/g,之后突出全球

var str ="Test abc test test abc test test test abc test test abc";str = str.replace(/abc/g, '');

如果你考虑重用,请创建一个函数来为你执行此操作,但不建议这样做,因为它只有一行函数。但是,如果你大量使用它,你可以这样写:

String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {return this.replace(new RegExp(string, 'g'), replaced);};

只需在您的代码中一遍又一遍地使用它,如下所示:

var str ="Test abc test test abc test test test abc test test abc";str = str.replaceAll('abc', '');

但正如我之前提到的,它在要编写的行或性能方面不会有太大的区别。只有缓存函数可能会影响长字符串的更快性能,如果你想重用DRY代码也是一个很好的做法。

在我的应用程序中,我使用了一个为此目的最强大的自定义函数,甚至在更简单的情况下包装split/join解决方案,它在Chrome60和Firefox 54(JSBEN.CH)中比其他解决方案快一点。

优点是这个自定义函数可以使用字符串或字符同时处理许多替换,这可能是某些应用程序的快捷方式。

与上面的拆分/加入解决方案一样,下面的解决方案与转义字符没有任何问题,与正则表达式方法不同。

function replaceAll(s, find, repl, caseOff, byChar) {if (arguments.length<2)return false;var destDel = ! repl;       // If destDel delete all keys from targetvar isString = !! byChar;   // If byChar, replace set of charactersif (typeof find !== typeof repl && ! destDel)return false;if (isString && (typeof find !== "string"))return false;
if (! isString && (typeof find === "string")) {return s.split(find).join(destDel ? "" : repl);}
if ((! isString) && (! Array.isArray(find) ||(! Array.isArray(repl) && ! destDel)))return false;
// If destOne replace all strings/characters by just one elementvar destOne = destDel ? false : (repl.length === 1);
// Generally source and destination should have the same sizeif (! destOne && ! destDel && find.length !== repl.length)return false
var prox, sUp, findUp, i, done;if (caseOff)  { // Case insensitive
// Working with uppercase keys and targetsUp = s.toUpperCase();if (isString)findUp = find.toUpperCase()elsefindUp = find.map(function(el) {return el.toUpperCase();});}else { // Case sensitivesUp = s;findUp = find.slice(); // Clone array/string}
done = new Array(find.length); // Size: number of keysdone.fill(null);
var pos = 0;  // Initial position in target svar r = "";   // Initial resultvar aux, winner;while (pos < s.length) {       // Scanning the targetprox  = Number.MAX_SAFE_INTEGER;winner = -1;  // No winner at the startfor (i=0; i<findUp.length; i++) // Find next occurence for each stringif (done[i]!==-1) { // Key still alive
// Never search for the word/char or is over?if (done[i] === null || done[i] < pos) {aux = sUp.indexOf(findUp[i], pos);done[i] = aux;  // Save the next occurrence}elseaux = done[i]   // Restore the position of last search
if (aux < prox && aux !== -1) { // If next occurrence is minimumwinner = i; // Save itprox = aux;}} // Not done
if (winner === -1) { // No matches forwardr += s.slice(pos);break;} // No winner
// Found the character or string key in the target
i = winner;  // Restore the winnerr += s.slice(pos, prox); // Update piece before the match
// Append the replacement in targetif (! destDel)r += repl[destOne ? 0 : i];pos = prox + (isString ? 1 : findUp[i].length); // Go after match}  // Loop
return r; // Return the resulting string}

留档如下:

 replaceAll
Syntax======
replaceAll(s, find, [repl, caseOff, byChar)
Parameters==========
"s" is a string target of replacement."find" can be a string or array of strings."repl" should be the same type than "find" or empty
If "find" is a string, it is a simple replacement forall "find" occurrences in "s" by string "repl"
If "find" is an array, it will replaced each string in "find"that occurs in "s" for corresponding string in "repl" array.The replace specs are independent: A replacement part cannotbe replaced again.

If "repl" is empty all "find" occurrences in "s" will be deleted.If "repl" has only one character or element,all occurrences in "s" will be replaced for that one.
"caseOff" is true if replacement is case insensitive(default is FALSE)
"byChar" is true when replacement is based on set of characters.Default is false
If "byChar", it will be replaced in "s" all characters in "find"set of characters for corresponding character in "repl"set of characters
Return======
The function returns the new string after the replacement.

公平地说,我在没有参数测试的情况下运行了基准

这是我的测试集,使用Node.js:

function l() {return console.log.apply(null, arguments);}
var k = 0;l(++k, replaceAll("banana is a ripe fruit harvested near the river",["ri", "nea"], ["do", "fa"]));  // 1l(++k, replaceAll("banana is a ripe fruit harvested near the river",["ri", "nea"], ["do"])); // 2l(++k, replaceAll("banana is a ripe fruit harvested near the river",["ri", "nea"])); // 3l(++k, replaceAll("banana is a ripe fruit harvested near the river","aeiou", "", "", true)); // 4l(++k, replaceAll("banana is a ripe fruit harvested near the river","aeiou", "a", "", true)); // 5l(++k, replaceAll("banana is a ripe fruit harvested near the river","aeiou", "uoiea", "", true)); // 6l(++k, replaceAll("banana is a ripe fruit harvested near the river","aeiou", "uoi", "", true)); // 7l(++k, replaceAll("banana is a ripe fruit harvested near the river",["ri", "nea"], ["do", "fa", "leg"])); // 8l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",["ri", "nea"], ["do", "fa"])); // 9l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",["ri", "nea"], ["do", "fa"], true)); // 10return;

以及结果:

1'香蕉是远在多佛收获的毒品水果'
2'香蕉是多佛收获的一种毒品水果'
3'香蕉是收获的一种水果'
4'bnn s rp frt hrvstd nr th rvr'
5'banana as a rapa fraat哈佛'
6'bununu is u ripo frait hurvostod nour tho rivor'
7 false
8 false
9“香蕉是河边采摘的熟果”
10'香蕉是多佛收获的多普水果'

如果字符串包含类似于abccc的模式,您可以使用:

str.replace(/abc(\s|$)/g, "")

在字符串中搜索和替换第一个元素

var str = '[{"id":1,"name":"karthikeyan.a","type":"developer"}]'var i = str.replace('"[','[').replace(']"',']');console.log(i,'//first element search and replace')

在字符串中全局搜索和替换

var str = '[{"id":1,"name":"karthikeyan.a","type":"developer"}]'var j = str.replace(/\"\[/g,'[').replace(/\]\"/g,']');console.log(j,'//global search and replace')

使用

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

对我来说比以前的答案更好。所以new RegExp("abc", 'g')创建了一个与文本("abc")的所有出现('g'标志)匹配的正则表达式。第二部分是被替换为的内容,在您的情况下为空字符串("")。str是字符串,我们必须覆盖它,因为replace(...)只返回结果,而不是覆盖。在某些情况下,您可能想要使用它。

我只是想分享我的解决方案,基于JavaScript最新版本的一些功能特性:

   var str = "Test abc test test abc test test test abc test test abc";
var result = str.split(' ').reduce((a, b) => {return b == 'abc' ? a : a + ' ' + b;   })
console.warn(result)

对于独特可替换值

String.prototype.replaceAll = function(search_array, replacement_array) {//var target = this;//search_array.forEach(function(substr, index) {if (typeof replacement_array[index] != "undefined") {target = target.replace(new RegExp(substr, 'g'), replacement_array[index])}});//return target;};
//  Use:var replacedString = "This topic commented on :year. Talking :question.".replaceAll([':year', ':question'], ['2018', 'How to replace all occurrences of a string in JavaScript']);//console.log(replacedString);

在与主要答案相关的性能方面,这是一些在线测试

下面是一些使用console.time()的性能测试(它们在您自己的控制台中效果最好,因为在下面的代码片段中可以看到时间很短)。

console.time('split and join');"javascript-test-find-and-replace-all".split('-').join(' ');console.timeEnd('split and join')
console.time('regular expression');"javascript-test-find-and-replace-all".replace(new RegExp('-', 'g'), ' ');console.timeEnd('regular expression');
console.time('while');let str1 = "javascript-test-find-and-replace-all";while (str1.indexOf('-') !== -1) {str1 = str1.replace('-', ' ');}console.timeEnd('while');

有趣的是,如果您多次运行它们,结果总是不同的,即使正则表达式解决方案平均看起来最快,while循环解决方案最慢。

前面的答案太复杂了。只需像这样使用替换函数:

str.replace(/your_regex_pattern/g, replacement_string);

示例:

var str = "Test abc test test abc test test test abc test test abc";
var res = str.replace(/[abc]+/g, "");
console.log(res);

你可以试试这样:

示例数据:

var text = "heloo,hai,hei"
text = text.replace(/[,]+/g, '')

text.forEach((value) => {hasil = hasil.replace(',', '')})

方法1

尝试实现一个正则表达式:

"测试abc测试abc测试abc测试abc测试abc测试abc"替换(/\abc/g, ' ');

方法2

拆分并连接。使用abc拆分并使用空格连接。

最好的解决方案,为了替换任何字符,我们使用indexOf()includes()substring()函数将匹配的字符串替换为当前字符串中提供的字符串。

  • #0函数是查找nth匹配索引位置。
  • #0方法确定是否可以在另一个字符串中找到一个字符串,并根据需要返回true或false。
  • #0函数是获取String(precedingexceding)的部分。在这些部分之间添加替换字符串以生成最终返回字符串。

以下函数允许使用任何字符。
其中#0不允许像**这样的特殊字符,有些字符需要转义,像$

String.prototype.replaceAllMatches = function(obj) { // Obj format: { 'matchkey' : 'replaceStr' }var retStr = this;for (var x in obj) {//var matchArray = retStr.match(new RegExp(x, 'ig'));//for (var i = 0; i < matchArray.length; i++) {var prevIndex = retStr.indexOf(x); // matchkey = '*', replaceStr = '$*' While loop never ends.while (retStr.includes(x)) {retStr = retStr.replaceMatch(x, obj[x], 0);var replaceIndex = retStr.indexOf(x);if( replaceIndex <  prevIndex + (obj[x]).length) {break;} else {prevIndex = replaceIndex;}}}return retStr;};String.prototype.replaceMatch = function(matchkey, replaceStr, matchIndex) {var retStr = this, repeatedIndex = 0;//var matchArray = retStr.match(new RegExp(matchkey, 'ig'));//for (var x = 0; x < matchArray.length; x++) {for (var x = 0; (matchkey != null) && (retStr.indexOf(matchkey) > -1); x++) {if (repeatedIndex == 0 && x == 0) {repeatedIndex = retStr.indexOf(matchkey);} else { // matchIndex > 0repeatedIndex = retStr.indexOf(matchkey, repeatedIndex + 1);}if (x == matchIndex) {retStr = retStr.substring(0, repeatedIndex) + replaceStr + retStr.substring(repeatedIndex + (matchkey.length));matchkey = null; // To break the loop.}}return retStr;};

我们还可以使用正则表达式对象将文本与模式匹配。以下是将使用正则表达式对象的函数。

当您使用无效正则表达式模式(如'**')时,您将获得Syn的错误。

  • #0函数用于将指定的String替换为给定的String。
  • #0函数是查找字符串重复的次数。
  • #0方法执行搜索正则表达式和指定字符串之间的匹配。返回true或false。
String.prototype.replaceAllRegexMatches = function(obj) { // Obj format: { 'matchkey' : 'replaceStr' }var retStr = this;for (var x in obj) {retStr = retStr.replace(new RegExp(x, 'ig'), obj[x]);}return retStr;};

请注意,正则表达式是不带引号编写的。


使用上述功能的示例:

var str = "yash yas $dfdas.**";console.log('String: ', str);
// No need to escape any special characterconsole.log('Index matched replace: ', str.replaceMatch('as', '*', 2));console.log('Index Matched replace: ', str.replaceMatch('y', '~', 1));console.log('All Matched replace: ', str.replaceAllMatches({'as': '**', 'y':'Y', '$':'-'}));console.log('All Matched replace : ', str.replaceAllMatches({'**': '~~', '$':'&$&', '&':'%', '~':'>'}));
// You need to escape some special Charactersconsole.log('REGEX all matched replace: ', str.replaceAllRegexMatches({'as' : '**', 'y':'Y', '\\$':'-'}));

结果:

String:  yash yas $dfdas.**Index Matched replace:  yash yas $dfd*.**Index Matched replace:  yash ~as $dfdas.**
All Matched replace:  Y**h Y** -dfd**.**All Matched replace:  yash yas %$%dfdas.>>
REGEX All Matched replace:  Y**h Y** -dfd**.**

最简单的解决方案——

let str = "Test abc test test abc test test test abc test test abc";
str = str.split(" ");str = str.filter((ele, key)=> ele!=="abc")str = str.join(" ")

或者干脆-

str = str.split(" ").filter((ele, key) => ele != "abc").join(" ")

这可以使用正则表达式来实现。一些可能对某人有所帮助的组合:

var word = "this,\\ .is*a*test,    '.and? / only /     'a \ test?";var stri = "This      is    a test         and only a        test";

要替换所有非alpha字符,

console.log(word.replace(/([^a-z])/g,' ').replace(/ +/g, ' '));Result: [this is a test and only a test]

用一个空间替换多个连续空间,

console.log(stri.replace(/  +/g,' '));Result: [This is a test and only a test]

要替换所有*字符,

console.log(word.replace(/\*/g,''));Result: [this,\ .isatest,    '.and? / only /     'a  test?]

替换问号(?)

console.log(word.replace(/\?/g,'#'));Result: [this,\ .is*a*test,    '.and# / only /     'a  test#]

要替换引号,

console.log(word.replace(/'/g,'#'));Result: [this,\ .is*a*test,    #.and? / only /     #a  test?]

要替换所有字符,

console.log(word.replace(/,/g,''));Result: [this\ .is*a*test    '.and? / only /     'a  test?]

要替换一个特定的词,

console.log(word.replace(/test/g,''));Result: [this,\ .is*a*,    '.and? / only /     'a  ?]

要替换反斜杠,

console.log(word.replace(/\\/g,''));Result: [this, .is*a*test,    '.and? / only /     'a  test?]

要替换正斜杠,

console.log(word.replace(/\//g,''));Result: [this,\ .is*a*test,    '.and?  only      'a  test?]

替换所有空格,

console.log(word.replace(/ /g,'#'));Result: [this,\#.is*a*test,####'.and?#/#only#/#####'a##test?]

为了替换点,

console.log(word.replace(/\./g,'#'));Result: [this,\ #is*a*test,    '#and? / only /     'a  test?]
var myName = 'r//i//n//o//l////d';var myValidName = myName.replace(new RegExp('\//', 'g'), ''); > // rinoldconsole.log(myValidName);
var myPetName = 'manidog';var renameManiToJack = myPetName.replace(new RegExp('mani', 'g'), 'jack'); > // jackdog

这些是最常见和最可读的方法。

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

方法一:

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

方法二:

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

方法三:

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

方法4:

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

我使用拆分和连接或此函数:

function replaceAll(text, busca, reemplaza) {while (text.toString().indexOf(busca) != -1)text = text.toString().replace(busca, reemplaza);return text;}

这应该能行。

String.prototype.replaceAll = function (search, replacement) {var str1 = this.replace(search, replacement);var str2 = this;while(str1 != str2) {str2 = str1;str1 = str1.replace(search, replacement);}return str1;}

示例:

Console.log("Steve is the best character in Minecraft".replaceAll("Steve", "Alex"));

不使用任何正则表达式的最简单方法是分割加入,就像这里的代码一样:

var str = "Test abc test test abc test test test abc test test abc";console.log(str.split('abc').join(''));

所有的答案都被接受了,你可以用很多方法做到这一点。其中一个诀窍是这样的:

const str = "Test abc test test abc test test test abc test test abc";
const compare = "abc";arrayStr = str.split(" ");arrayStr.forEach((element, index) => {if (element == compare) {arrayStr.splice(index, 1);}});const newString = arrayStr.join(" ");console.log(newString);

要替换一次,请使用:

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

要多次更换,请使用:

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

检查这个答案。也许它会有帮助,我在我的项目中使用了它。

function replaceAll(searchString, replaceString, str) {return str.split(searchString).join(replaceString);}
replaceAll('abc', '',"Test abc test test abc test test test abc test test abc" ); // "Test  test test  test test test  test test "

您可以在没有Regex的情况下执行此操作,但如果替换文本包含搜索文本,则需要小心。

e. g.

replaceAll("nihIaohi", "hI", "hIcIaO", true)

所以这里是一个适当的变体replace All,包括string-原型:

function replaceAll(str, find, newToken, ignoreCase){let i = -1;
if (!str){// Instead of throwing, act as COALESCE if find == null/empty and str == nullif ((str == null) && (find == null))return newToken;
return str;}
if (!find) // sanity checkreturn str;
ignoreCase = ignoreCase || false;find = ignoreCase ? find.toLowerCase() : find;
while ((i = (ignoreCase ? str.toLowerCase() : str).indexOf(find, i >= 0 ? i + newToken.length : 0)) !== -1){str = str.substring(0, i) +newToken +str.substring(i + find.length);} // Whend
return str;}

或者,如果你想要一个字符串原型函数:

String.prototype.replaceAll = function (find, replace) {let str = this;
let i = -1;
if (!str){// Instead of throwing, act as COALESCE if find == null/empty and str == nullif ((str == null) && (find == null))return newToken;
return str;}
if (!find) // sanity checkreturn str;
ignoreCase = ignoreCase || false;find = ignoreCase ? find.toLowerCase() : find;
while ((i = (ignoreCase ? str.toLowerCase() : str).indexOf(find, i >= 0 ? i + newToken.length : 0)) !== -1){str = str.substring(0, i) +newToken +str.substring(i + find.length);} // Whend
return str;};
str = "Test abc test test abc test test test abc test test abc"
str.split(' ').join().replace(/abc/g,'').replace(/,/g, ' ')

现在有一个完成提案用于将String.prototype.replaceAll集成到官方规范中。最终,开发人员不必为replaceAll提出自己的实现-相反,现代JavaScript引擎将原生支持它。

建议是在第4阶段,这意味着,一切都完成了,剩下的就是浏览器开始实现它。

它在最新版本的Chrome,Firefox和Safari中排名第0。

以下是实施细节:

根据当前的TC39共识,String.prototype.replaceAll在所有情况下的行为与String.prototype.replace相同,除了在以下两种情况下:

  1. 如果searchValue是一个字符串,String.prototype.replace仅替换searchValue的一次出现,而String.prototype.replaceAll替换searchValue所有次出现(就好像使用了.split(searchValue).join(replaceValue)或全局&正确转义的正则表达式)。
  2. 如果searchValue是非全局正则表达式,则String.prototype.replace替换单个匹配,而String.prototype.replaceAll抛出异常。这样做是为了避免缺少全局标志(暗示“不要替换所有”)和被调用方法的名称(强烈暗示“替换所有”)之间的固有混淆。

值得注意的是,如果searchValue是全局正则表达式,则String.prototype.replaceAll的行为与String.prototype.replace相同。

您可以看到符合规范的聚填充这里

在支持的环境中,以下代码段将记录foo-bar-baz,而不会引发错误:

const str = 'foo bar baz';console.log(str.replaceAll(' ', '-'));

截至2020年8月,ECMAScript有第四阶段提案#0方法添加到String

现在支持Chrome85+、Edge 85+、Firefox 77+、Safari13.1+

用法与#0方法相同:

String.prototype.replaceAll(searchValue, replaceValue)

下面是一个示例用法:

'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'

它在大多数现代浏览器中得到支持,但也存在Poly填充:

它在实验标志--harmony-string-replaceall后面的V8引擎中得到支持。阅读更多关于v8网站.

看看这个。我相信它会帮助你:

<!DOCTYPE html><html><body><p>Click the button to do a global search and replace for "is" in a string.</p><button onclick="myFunction()">Try it</button><p id="demo"></p><script>function myFunction() {var str = 'Is this "3" dris "3"?';var allvar= '"3"';var patt1 = new RegExp( allvar, 'g' );document.getElementById("demo").innerHTML = str.replace(patt1,'"5"');}</script></body></html>

这里是jsfiddle链接

2019年11月,JavaScript添加了一个新功能string.prototype.replaceAll()

目前只有巴别塔支持它,但也许将来它可以在所有浏览器中实现。有关更多信息,在这里阅读

性能

今天27.12.2019我对所选解决方案的macOS v10.13.6(高塞拉利昂)进行测试。

结论

  • str.replace(/abc/g, '');C)是一个很好的跨浏览器快速解决方案,适用于所有字符串。
  • 基于split-joinA,B)或replaceC、D)的解决方案很快
  • 基于whileE、F、G、H)的解决方案很慢-通常小字符串慢约4倍,长字符串慢约3000倍(!)
  • 递归解决方案(RA、RB)很慢,不适用于长字符串

我还创建了自己的解决方案。目前看起来它是完成问题工作的最短的一个:

str.split`abc`.join``

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

详情

测试在Chrome79.0、Safari13.0.4和Firefox 71.0(64位)上执行。测试RARB使用递归。结果

在此处输入图片描述

短字符串-55个字符

您可以在机器这里上运行测试。Chrome的结果:

在此处输入图片描述

长字符串:275 000个字符

递归解RARB给出了

RangeError:超出最大调用堆栈大小

对于1M人物,他们甚至打破Chrome

在此处输入图片描述

我尝试为其他解决方案执行1M字符的测试,但是E、F、G、H需要太多时间,浏览器要求我打破脚本,所以我缩小测试字符串以275K字符。您可以在您的机器这里上运行测试。Chrome的结果

在此处输入图片描述

测试中使用的代码

var t="Test abc test test abc test test test abc test test abc"; // .repeat(5000)var log = (version,result) => console.log(`${version}: ${result}`);

function A(str) {return str.split('abc').join('');}
function B(str) {return str.split`abc`.join``; // my proposition}

function C(str) {return str.replace(/abc/g, '');}
function D(str) {return str.replace(new RegExp("abc", "g"), '');}
function E(str) {while (str.indexOf('abc') !== -1) { str = str.replace('abc', ''); }return str;}
function F(str) {while (str.indexOf('abc') !== -1) { str = str.replace(/abc/, ''); }return str;}
function G(str) {while(str.includes("abc")) { str = str.replace('abc', ''); }return str;}
// src: https://stackoverflow.com/a/56989553/860099function H(str){let i = -1let find = 'abc';let newToken = '';
if (!str){if ((str == null) && (find == null)) return newToken;return str;}
while ((i = str.indexOf(find, i >= 0 ? i + newToken.length : 0)) !== -1){str = str.substring(0, i) +newToken +str.substring(i + find.length);}return str;}
// src: https://stackoverflow.com/a/22870785/860099function RA(string, prevstring) {var omit = 'abc';var place = '';if (prevstring && string === prevstring)return string;prevstring = string.replace(omit, place);return RA(prevstring, string)}
// src: https://stackoverflow.com/a/26107132/860099function RB(str) {var find = 'abc';var replace = '';var i = str.indexOf(find);if (i > -1){str = str.replace(find, replace);i = i + replace.length;var st2 = str.substring(i);if(st2.indexOf(find) > -1){str = str.substring(0,i) + RB(st2, find, replace);}}return str;}



log('A ', A(t));log('B ', B(t));log('C ', C(t));log('D ', D(t));log('E ', E(t));log('F ', F(t));log('G ', G(t));log('H ', H(t));log('RA', RA(t)); // use reccurencelog('RB', RB(t)); // use reccurence
<p style="color:red">This snippet only presents codes used in tests. It not perform test itself!<p>

我们可以在JavaScript中使用取代方法:

var result = yourString.replace('regexPattern', "replaceString");

var str = "Test abc test test abc test test test abc test test abc";
var expectedString = str.replace(/abc(\s|$)/g, "");
console.log(expectedString);

我知道这不是最好的方法,但你可以试试这个:

var annoyingString = "Test abc test test abc test test test abc test test abc";
while (annoyingString.includes("abc")) {annoyingString = annoyingString.replace("abc", "")}

我在“库”部分的此性能测试页面中添加了以下功能:

https://jsben.ch/LFfWA

function _replace(t, s, r){var i = t.indexOf(s);if (i == -1) return t;return t.slice(0, i) + r + _replace(t.slice(i + s.length, t.length), s,r);}

…并把这个作为测试:

var replaced = _replace(testString, 'abc', '123');

…并且该函数的执行速度比拆分或正则表达式快34%。我们的想法/希望是最终将越来越小的字符串片段粘贴到堆栈上,然后通过展开堆栈来构建整个结果,从而最大限度地减少额外的字符串副本和通过相同字符串数据进行的额外搜索,并有望优化CPU缓存的使用。

部分想法是,如果字符串不是太大,它可能最终会进入CPU缓存;传递它并粘贴它的片段将这些位放入缓存中,然后搜索可以完全使用CPU缓存的数据进行操作。现在,我确信这是否真的发生了完全取决于JavaScript实现。

这不是尽可能快,但它是我在没有可变字符串的情况下管理的最快的。JavaScript中的数组可能每个元素都有一个指针,因此,涉及大量数组元素的解决方案不太可能像这样对CPU缓存友好。

从v85开始,Chrome现在本机支持String.prototype.replaceAll。请注意,这优于所有其他建议的解决方案,应该在主要支持的情况下使用。

功能状态:https://chromestatus.com/feature/6040389083463680

var s = "hello hello world";s = s.replaceAll("hello", ""); // s is now "world"console.log(s)

这是一个非常简单的解决方案。您可以将新方法分配给String对象

String.prototype.replaceAll = function(search, replace){return this.replace(new RegExp(search, 'g'), replace)}
var str = "Test abc test test abc test test test abc test test abc";str = str.replaceAll('abc', '');
console.log(str) // -> Test  test test  test test test  test test

使用分裂加入

var str = "Test abc test test abc test test test abc test test abc";var replaced_str = str.split('abc').join('');console.log(replaced_str);

我建议为string类添加一个全局方法,将其附加到原型链中。

String.prototype.replaceAll = function(fromReplace, toReplace, {ignoreCasing} = {}) { return this.replace(new RegExp(fromReplace, ignoreCasing ? 'ig': 'g'), toReplace);}

它可以像这样使用:

'stringwithpattern'.replaceAll('pattern', 'new-pattern')

2020年8

没有更多的正则表达式

const str = "Test abc test test abc test test test abc test test abc";const modifiedStr = str.replaceAll('abc', '');console.log(modifiedStr);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll

此解决方案结合了之前的一些答案,并且更符合2020年8月提出的标准解决方案。该解决方案在2020年9月对我来说仍然可行,因为String.replaceAll在我使用的Node.js二进制文件中不可用。


RegExp.escape是一个需要处理的单独问题,但在这里很重要,因为官方提出的解决方案将自动转义基于stringfind输入。这个String.replaceAll的多边形填充不会没有RegExp.escape逻辑。

我已经添加了一个答案,它不使用PolyFillRegExp.Escape,如果你不希望这样的话。


如果您将正则表达式传递给find,则<强>必须g作为标志。这聚填充不会为您提供好的TypeError,并会给您带来重大的错误时间。

如果你需要精确的标准一致性,对于一个严格依赖标准实现的应用程序,那么我建议使用巴别塔或其他工具每次都能得到“正确答案”,而不是Stack Overflow。这样你就不会有任何惊喜。


代码:

if (!Object.prototype.hasOwnProperty.call(RegExp, 'escape')) {RegExp.escape = function(string) {// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping// https://github.com/benjamingr/RegExp.escape/issues/37return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string};}
if (!Object.prototype.hasOwnProperty.call(String, 'replaceAll')) {String.prototype.replaceAll = function(find, replace) {// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll// If you pass a RegExp to 'find', you _MUST_ include 'g' as a flag.// TypeError: "replaceAll must be called with a global RegExp" not included, will silently cause significant errors. _MUST_ include 'g' as a flag for RegExp.// String parameters to 'find' do not require special handling.// Does not conform to "special replacement patterns" when "Specifying a string as a parameter" for replace// Does not conform to "Specifying a function as a parameter" for replacereturn this.replace(Object.prototype.toString.call(find) == '[object RegExp]' ?find :new RegExp(RegExp.escape(find), 'g'),replace);}}

代码,缩小:

Object.prototype.hasOwnProperty.call(RegExp,"escape")||(RegExp.escape=function(e){return e.replace(/[.*+\-?^${}()|[\]\\]/g,"\\$&")}),Object.prototype.hasOwnProperty.call(String,"replaceAll")||(String.prototype.replaceAll=function(e,t){return this.replace("[object RegExp]"==Object.prototype.toString.call(e)?e:new RegExp(RegExp.escape(e),"g"),t)});

示例:

console.log('t*.STVAL'.replaceAll(new RegExp(RegExp.escape('T*.ST'), 'ig'),'TEST'));
console.log('t*.STVAL'.replaceAll('t*.ST','TEST'););

没有RegExp.Escape的代码:

if (!Object.prototype.hasOwnProperty.call(String, 'replaceAll')) {String.prototype.replaceAll = function(find, replace) {// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll// If you pass a RegExp to 'find', you _MUST_ include 'g' as a flag.// TypeError: "replaceAll must be called with a global RegExp" not included, will silently cause significant errors. _MUST_ include 'g' as a flag for RegExp.// String parameters to 'find' do not require special handling.// Does not conform to "special replacement patterns" when "Specifying a string as a parameter" for replace// Does not conform to "Specifying a function as a parameter" for replacereturn this.replace(Object.prototype.toString.call(find) == '[object RegExp]' ?find :new RegExp(find.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'), 'g'),replace);}}

没有RegExp.Escape的代码,缩小:

Object.prototype.hasOwnProperty.call(String,"replaceAll")||(String.prototype.replaceAll=function(e,t){return this.replace("[object RegExp]"==Object.prototype.toString.call(e)?e:new RegExp(e.replace(/[.*+\-?^${}()|[\]\\]/g,"\\$&"),"g"),t)});

有一种方法可以使用新的replaceAll()方法。

但是您需要使用尖端浏览器或JavaScript运行时环境。

您可以在这里中检查浏览器兼容性。

JavaScript提供了一种直接的方法来用另一个字符串替换字符串的一部分,并且还有一些技巧可以做到这一点。

要替换所有出现的情况,您可以在JavaScript中使用replace()replaceAll方法。

  1. replace() method-要使用此方法替换所有元素,请使用正则表达式作为模式来查找匹配的字符串,然后将其替换为新字符串。请考虑使用/g标志。

const str = "To do or not to do";const pattern = /do/g;const replaceBy = "Code";console.log(str.replace(pattern, replaceBy));

  1. replaceAll() method-要使用此方法替换所有元素,请使用字符串或正则表达式作为模式来查找匹配的字符串,然后将其替换为新字符串。我们必须在全部替换方法中使用/g标志和正则表达式。

const str = "To do or not to do";const pattern = "do";const replaceBy = "Code";console.log(str.replaceAll(pattern, replaceBy));
const pattern2 = /do/g;console.log(str.replaceAll(pattern2, replaceBy));

替代方法:通过使用拆分和连接方法

在要替换的位置拆分字符串,并使用新字符串作为分隔符连接。参见示例。

const str = "To do or not to do";const newStr = str.split("do").join("Code");console.log(newStr);

// Try this way
const str = "Test abc test test abc test test test abc test test abc";const result = str.split('abc').join('');console.log(result);

使用不区分大小写的正则表达式<强>i标志

console.log('App started'.replace(/a/g, '')) // Result: "App strted"console.log('App started'.replace(/a/gi, '')) // Result: "pp strted"

经过几次尝试和大量失败后,我发现以下功能似乎是浏览器兼容性和易用性方面最好的全能解决方案。这是我发现的唯一适用于旧浏览器的解决方案。(是的,即使旧浏览器不被鼓励和过时,一些遗留应用程序仍然大量使用OLE浏览器(例如旧的Visual Basic 6应用程序或带有表单的Excel. xlsm宏。)

无论如何,这是简单的函数。

function replaceAll(str, match, replacement){return str.split(match).join(replacement);}

重复,直到你把它们全部替换掉:

const regex = /^>.*/im;while (regex.test(cadena)) {cadena = cadena.replace(regex, '*');}

#0-ECMAScript 2021

新的String.prototype.replaceAll()方法返回一个新字符串,其中模式的所有匹配项都被替换项替换。模式可以是字符串或RegExp,替换可以是字符串或要为每个匹配项调用的函数。

const message = 'dog barks meow meow';const messageFormatted = message.replaceAll('meow', 'woof')
console.log(messageFormatted);

我看了这篇问答,但是没有找到适合我的解决方案。虽然答案很有用,但我决定从头开始创建自己的解决方案。关于这种替换的问题是:

  • 通常,仅仅找到一个匹配任何大写或小写的字符串是不够的。例如,对于搜索结果,我需要用同一个箱子代替
  • 如果我处理innerHTML,我很容易损坏超文本标记语言标签(例如,在href属性中出现hr)。
  • 全部替换方法对于许多用例来说太新鲜了,它并不能解决所有问题。

所以,我正在编写函数来突出显示表格中的搜索结果,其中表格数据单元格内部可能有链接,以及其他超文本标记语言标签。这些链接旨在保留,所以innerText是不够的。

我决定为每个有相同问题的人提供的解决方案。当然,你不仅可以将其用于表,还可以用于任何元素。这是代码:

/* Iterate over table data cells to insert a highlight tag */function highlightSearchResults(textFilter) {textFilter = textFilter.toLowerCase().replace('<', '&lt;').replace('>', '&gt;');let tds;tb = document.getElementById('sometable'); //root element where to searchif (tb) {tds = tb.getElementsByTagName("td"); //sub-elements where to make replacements}if (textFilter && tds) {for (td of tds) {//specify your span class or whatever you need before and aftertd.innerHTML = insertCaseInsensitive(td.innerHTML, textFilter, '<span class="highlight">', '</span>');}}}
/* Insert a highlight tag */function insertCaseInsensitive(srcStr, lowerCaseFilter, before, after) {let lowStr = srcStr.toLowerCase();let flen = lowerCaseFilter.length;let i = -1;while ((i = lowStr.indexOf(lowerCaseFilter, i + 1)) != -1) {if (insideTag(i, srcStr)) continue;srcStr = srcStr.slice(0, i) + before + srcStr.slice(i, i+flen) + after + srcStr.slice(i+flen);lowStr = srcStr.toLowerCase();i += before.length + after.length;}return srcStr;}
/* Check if an ocurrence is inside any tag by index */function insideTag(si, s) {let ahead = false;let back = false;for (let i = si; i < s.length; i++) {if (s[i] == "<") {break;}if (s[i] == ">") {ahead = true;break;}}for (let i = si; i >= 0; i--) {if (s[i] == ">") {break;}if (s[i] == "<") {back = true;break;}}return (ahead && back);}

2021年的正确答案是:

String.prototype.replace全部()

console.log('Change this and this for me'.replaceAll('this','that') // Normal case);console.log('aaaaaa'.replaceAll('aa','a') // Challenged case);

如果你不想处理替换()+RegExp

但是如果浏览器是在2020年之前呢?

在这种情况下,我们需要多边形(强制旧浏览器支持新功能)(我认为几年将是必要的)。我在答案中找不到完全正确的方法。所以我建议这个函数将被定义为一个多边形。

我的建议选项replaceAll的聚酰亚胺:

replaceAll的聚填充(与全局标志错误)(更原则的版本)
if (!String.prototype.replaceAll) { // Check if the native function not existObject.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) Stringconfigurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)value: function(search, replace) { // Set the function by closest input names (For good info in consoles)return this.replace( // Using native String.prototype.replace()Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?? search.global // Is the RegEx global?? search // So pass it: function(){throw new TypeError('replaceAll called with a non-global RegExp argument')}() // If not throw an error: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExpreplace); // passing second argument}});}
replaceAll的Polyill(处理全局标志本身丢失)(我的第一个偏好)-为啥?
if (!String.prototype.replaceAll) { // Check if the native function not existObject.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) Stringconfigurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)value: function(search, replace) { // Set the function by closest input names (For good info in consoles)return this.replace( // Using native String.prototype.replace()Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?? search.global // Is the RegEx global?? search // So pass it: RegExp(search.source, /\/([a-z]*)$/.exec(search.toString())[1] + 'g') // If not, make a global clone from the RegEx: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExpreplace); // passing second argument}});}
缩写(我的第一个偏好):
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
试试看:

if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
console.log('Change this and this for me'.replaceAll('this','that')); // Change that and that for me
console.log('aaaaaa'.replaceAll('aa','a')); // aaa
console.log('{} (*) (*) (RegEx) (*) (\*) (\\*) [reserved characters]'.replaceAll('(*)','X')); // {} X X (RegEx) X X (\*) [reserved characters]
console.log('How (replace) (XX) with $1?'.replaceAll(/(xx)/gi,'$$1')); // How (replace) ($1) with $1?
console.log('Here is some numbers 1234567890 1000000 123123.'.replaceAll(/\d+/g,'***')); // Here is some numbers *** *** *** and need to be replaced.
console.log('Remove numbers under 233: 236   229  711   200   5'.replaceAll(/\d+/g, function(m) {return parseFloat(m) < 233 ? '' : m})); // Remove numbers under 233: 236     711
console.log('null'.replaceAll(null,'x')); // x

// The difference between My first preference and the original:// Now in 2022 with browsers > 2020 it should throw an error (But possible it be changed in future)
//   console.log(//      'xyz ABC abc ABC abc xyz'.replaceAll(/abc/i,'')//   );
// Browsers < 2020:// xyz     xyz// Browsers > 2020// TypeError: String.prototype.replaceAll called with a non-global RegExp

浏览器支持:

在第一个参数输入的情况下,结果是与原生替换相同nullundefinedObjectFunctionDate,…,RegExpNumberString,…

参考:22.1.3.19String.prototype.replace全部(搜索值,替换值)+RegExp语法

重要提示:正如一些专业人士提到的那样,在答案中建议的许多递归函数将返回错误的结果。(用上面片段的挑战案例尝试它们。)也许一些棘手的方法,如#0或一些管理良好的函数会给出相同的结果,但肯定比native replaceAll()/polyfill replaceAll()/replace() + RegExp性能低得多


其他的polpill赋值方法

幼稚,但支持更旧的浏览器(最好避免)

例如,我们也可以支持IE7+,不使用Object.define属性()并使用我以前的朴素赋值方法:

if (!String.prototype.replaceAll) {String.prototype.replaceAll = function(search, replace) { // <-- Naive method for assignment// ... (Polyfill code Here)}}

它应该可以在IE7+上正常使用。
但是,正如这里@sebastian-simon解释的那样,在更高级的使用情况下,这可能会产生次要问题。例如:

for (var k in 'hi') console.log(k);// 0// 1// replaceAll  <-- ?
完全可信,但是很重

事实上,我的建议有点乐观。就像我们信任环境(浏览器和Node.js)一样,它肯定是2012-2021年左右。而且它是标准/著名,所以不需要任何特殊考虑。

但是即使是较旧的浏览器也可能会出现一些意想不到的问题,而PolyFill仍然可以支持和解决更多可能的环境问题。因此,如果我们需要尽可能大的支持,我们可以使用polpill库,例如:

https://polyfill.io/

特别是全部替换

<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>