提问人:Ali 提问时间:7/18/2009 最后编辑:Mateen UlhaqAli 更新时间:3/26/2023 访问量:4468444
如何替换 JavaScript 中所有出现的字符串?
How do I replace all occurrences of a string in JavaScript?
问:
给定一个字符串:
s = "Test abc test test abc test test test abc test test abc";
这似乎只删除了上面字符串中出现的第一个:abc
s = s.replace('abc', '');
如何替换所有出现的它?
答:
与全局正则表达式匹配:
anotherString = someString.replace(/cat/g, 'dog');
截至 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);
}
注意:正则表达式包含特殊(元)字符,因此,在上面的函数中盲目传递参数而不对其进行预处理以转义这些字符是危险的。这在Mozilla开发者网络的JavaScript正则表达式指南中有所介绍,其中提供了以下实用函数(自最初编写此答案以来,该函数至少更改了两次,因此请务必查看MDN站点以获取潜在的更新):find
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);
}
评论
escapeRegExp
]
}
.replace(/[.^$*+?()[{|\\]/g, "\\$&")
escapeRegExp
$&
replace
replace.replace(/\$/g, '$$$$')
replaceAll('abc def abc', 'abc', '$&@%#!') // Censor 'abc'
replaceAll()
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
结论:
如果您有性能关键型用例(例如,处理数百个字符串),请使用正则表达式方法。但对于大多数典型用例来说,这非常值得担心特殊字符。
评论
replaceAll
我的实现,非常不言自明
function replaceAll(string, token, newtoken) {
if(token!=newtoken)
while(string.indexOf(token) > -1) {
string = string.replace(token, newtoken);
}
return string;
}
评论
replaceAll("123434", "1234", "12")
"1234"
"12"
使用单词边界 (\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中将“ ' ”替换为“ '' ”
正则表达式不是替换子字符串的多次出现的唯一方法,远非如此。灵活思考,拆分思维!
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"
我的猜测是,这满足了您的需求。当然,它不是万无一失的,但它应该足以让你开始。我建议在这些页面上阅读更多内容。这将证明有助于完善此表达式以满足您的特定需求。
下面是与回调函数一起使用的示例。在这种情况下,它极大地简化了表达式并提供了更大的灵活性,例如用正确的大小写替换或一次性替换两者:.replace
cat
cats
'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
下面是一个基于已接受答案的字符串原型函数:
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;
}
评论
.indexOf
.indexOf
如果要查找的内容已在字符串中,并且手头没有正则表达式转义符,则可以使用 join/split:
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);
};
由于不太了解正则表达式在幕后如何工作的效率,我过去倾向于拆分和联接实现,而不考虑性能。当我想知道哪个更有效率,以及效率更高时,我以此为借口来找出答案。
在我的 Chrome Windows 8 机器上,基于正则表达式的实现速度最快,拆分和联接实现速度慢 53%。这意味着对于我使用的 lorem ipsum 输入,正则表达式的速度是其两倍。
查看此基准测试,将这两种实现相互运行。
正如 @ThomasLeduc 和其他人在下面的评论中指出的那样,如果包含某些在正则表达式中保留为特殊字符的字符,则基于正则表达式的实现可能存在问题。该实现假定调用方将事先对字符串进行转义,或者仅传递正则表达式 (MDN) 中表中没有字符的字符串。search
MDN 还提供了一个转义字符串的实现。如果这也被标准化为 ,那就太好了,但唉,它不存在:RegExp.escape(str)
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
我们可以在我们的实现中调用,但是,我不确定这会对性能产生多大影响(甚至可能对于不需要转义的字符串,例如所有字母数字字符串)。escapeRegExp
String.prototype.replaceAll
评论
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);
要替换所有类型的字符,请尝试以下代码:
假设我们需要在我的字符串中发送 “ 和 \。然后我们将它转换为“”,将\转换为\。
所以这种方法将解决这个问题。
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")
在我的递归替换中还有另一个带有变体的 jsperf,它们的速度更快 (http://jsperf.com/replace-all-vs-split-join/12)!
- 2017 年 7 月 27 日更新:看起来 RegExp 现在在最近发布的 Chrome 59 中具有最快的性能。
评论
while (str.indexOf('abc') !== -1)
{
str = str.replace('abc', '');
}
评论
如果使用库是您的一种选择,那么您将获得库功能附带的测试和社区支持的好处。例如,string.js 库有一个 replaceAll() 函数,可以执行您要查找的操作:
// 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”,并且我们希望删除所有重复的逗号。
[在这种情况下,可以执行 .replace(/,+/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,''')
// 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);
}
它将替换字符串 s 中出现的所有匹配项,直到可能为止:
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");
只需将此代码复制并粘贴到浏览器控制台中即可进行 TEST。
以下是原型的工作代码:
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;
}
评论
尽管人们提到了正则表达式的使用,但如果您想替换文本,而不管文本的大小写如何,还有更好的方法。如大写或小写。使用以下语法:
// Consider the below example
originalString.replace(/stringToBeReplaced/gi, '');
// The output will be all the occurrences removed irrespective of casing.
您可以参考此处的详细示例。
评论
假设您要用“x”替换所有“abc”:
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 代码的良好做法。
在我的应用程序中,我使用了为此目的最强大的自定义函数,即使将解决方案包装在更简单的情况下,它在 Chrome 60 和 Firefox 54 (JSBEN.CH)比其他溶液。我的电脑运行Windows 7 64位。split/join
优点是此自定义函数可以使用字符串或字符同时处理许多替换,这可以成为某些应用程序的快捷方式。
与上面的拆分/联接解决方案一样,下面的解决方案在转义字符方面没有任何问题,这与正则表达式方法不同。
function replaceAll(s, find, repl, caseOff, byChar) {
if (arguments.length<2)
return false;
var destDel = ! repl; // If destDel delete all keys from target
var isString = !! byChar; // If byChar, replace set of characters
if (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 element
var destOne = destDel ? false : (repl.length === 1);
// Generally source and destination should have the same size
if (! destOne && ! destDel && find.length !== repl.length)
return false
var prox, sUp, findUp, i, done;
if (caseOff) { // Case insensitive
// Working with uppercase keys and target
sUp = s.toUpperCase();
if (isString)
findUp = find.toUpperCase()
else
findUp = find.map(function(el) {
return el.toUpperCase();
});
}
else { // Case sensitive
sUp = s;
findUp = find.slice(); // Clone array/string
}
done = new Array(find.length); // Size: number of keys
done.fill(null);
var pos = 0; // Initial position in target s
var r = ""; // Initial result
var aux, winner;
while (pos < s.length) { // Scanning the target
prox = Number.MAX_SAFE_INTEGER;
winner = -1; // No winner at the start
for (i=0; i<findUp.length; i++) // Find next occurence for each string
if (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
}
else
aux = done[i] // Restore the position of last search
if (aux < prox && aux !== -1) { // If next occurrence is minimum
winner = i; // Save it
prox = aux;
}
} // Not done
if (winner === -1) { // No matches forward
r += s.slice(pos);
break;
} // No winner
// Found the character or string key in the target
i = winner; // Restore the winner
r += s.slice(pos, prox); // Update piece before the match
// Append the replacement in target
if (! 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 for all "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 cannot be 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"])); // 1
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
["ri", "nea"], ["do"])); // 2
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
["ri", "nea"])); // 3
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
"aeiou", "", "", true)); // 4
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
"aeiou", "a", "", true)); // 5
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
"aeiou", "uoiea", "", true)); // 6
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
"aeiou", "uoi", "", true)); // 7
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
["ri", "nea"], ["do", "fa", "leg"])); // 8
l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",
["ri", "nea"], ["do", "fa"])); // 9
l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",
["ri", "nea"], ["do", "fa"], true)); // 10
return;
结果如下:
1 “香蕉是多佛尔远地收获的水果”
2 “香蕉是多佛尔收获的水果”
3 “香蕉是收获的 pe 水果”
4 'BNN s rp frt hrvstd nr th rvr'
5 '香蕉是 rapa fraat harvastad naar tha ravar'
6 'Bununu is u ripo frait hurvostod nour tho rivor'
7 假 8 假
9 “香蕉是在河边收获的成熟水果”
10 '香蕉是一种收获的水果 faR THE DOVER'
评论
如果字符串包含类似的模式,例如 ,则可以使用以下命令: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'), "");
对我来说比以前的答案更好。因此,创建一个与文本 () 的所有出现 ( flag) 匹配的正则表达式。第二部分是被替换的内容,在本例中为空字符串 ()。 是字符串,我们必须覆盖它,因为只返回结果,而不是覆盖。在某些情况下,您可能希望使用它。new RegExp("abc", 'g')
'g'
"abc"
""
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”.replace(/\abc/g, ' ');
方法 2
拆分和联接。用 abc 拆分并用空白空间连接。
“测试 abc 测试测试 abc 测试测试测试 abc 测试测试 abc”.split(“abc”).join(“ ”)
最好的解决方案是,为了替换任何字符,我们使用 , , 和函数将匹配的字符串替换为当前字符串中提供的字符串。indexOf()
includes()
substring()
String.indexOf()
函数用于查找第 1 个匹配索引位置。n
String.includes()
方法确定是否可以在另一个字符串中找到一个字符串,并根据需要返回 true 或 false。String.substring
() 函数用于获取 String(,) 的各个部分。在这些部分之间添加替换 String 以生成最终返回的 String。preceding
exceding
以下函数允许使用任何字符。
其中,由于正则表达式
不允许某些特殊字符,例如某些字符需要转义,例如 .**
$
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 > 0
repeatedIndex = 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;
};
我们还可以使用正则表达式对象将文本与模式进行匹配。以下是将使用正则表达式对象的函数。
当您使用无效的正则表达式模式(如 )时,将收到 SyntaxError。'**'
String.replace()
函数用于将指定的 String 替换为给定的 String。String.match()
函数用于查找字符串重复的次数。RegExp.prototype.test
方法执行正则表达式与指定字符串之间的匹配项搜索。返回 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 character
console.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 Characters
console.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";
要替换所有非字母字符,
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'), ''); > // rinold
console.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"
方法1:
str = str.replace(/abc/g, "replaced text");
方法2:
str = str.split("abc").join("replaced text");
方法3:
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;
}
评论
replaceAll('aaaaaa','aa','a')
这应该有效。
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 "
您可以在没有正则表达式的情况下执行此操作,但如果替换文本包含搜索文本,则需要小心。
例如
replaceAll("nihIaohi", "hI", "hIcIaO", true)
所以这里是 replaceAll 的适当变体,包括 string-prototype:
function replaceAll(str, find, newToken, ignoreCase)
{
let i = -1;
if (!str)
{
// Instead of throwing, act as COALESCE if find == null/empty and str == null
if ((str == null) && (find == null))
return newToken;
return str;
}
if (!find) // sanity check
return 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 == null
if ((str == null) && (find == null))
return newToken;
return str;
}
if (!find) // sanity check
return 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, ' ')
现在已经有一个完整的提案,可以集成到官方规范中。最终,开发人员将不必提出自己的实现 - 相反,现代 JavaScript 引擎将原生支持它。String.prototype.replaceAll
replaceAll
该提案处于第 4 阶段,这意味着一切都已完成,剩下的就是让浏览器开始实现它。
它已在最新版本的 Chrome、Firefox 和 Safari 中提供。
以下是实施细节:
根据当前的 TC39 共识,除以下两种情况外,在所有情况下的行为都相同:
String.prototype.replaceAll
String.prototype.replace
- 如果是字符串,则仅替换 的单个匹配项,而替换 的所有匹配项(就好像使用了全局和正确转义的正则表达式一样)。
searchValue
String.prototype.replace
searchValue
String.prototype.replaceAll
searchValue
.split(searchValue).join(replaceValue)
- If 是非全局正则表达式,替换单个匹配项,而引发异常。这样做是为了避免缺少全局标志(这意味着“不要全部替换”)和被调用方法的名称(强烈建议“全部替换”)之间的固有混淆。
searchValue
String.prototype.replace
String.prototype.replaceAll
值得注意的是,其行为类似于 if 是全局正则表达式。
String.prototype.replaceAll
String.prototype.replace
searchValue
在受支持的环境中,以下代码片段将记录 ,而不会引发错误:foo-bar-baz
const str = 'foo bar baz';
console.log(
str.replaceAll(' ', '-')
);
截至 2020 年 8 月,ECMAScript 有一个第 4 阶段建议,该建议将 replaceAll
方法添加到 .String
Chrome 85+、Edge 85+、Firefox 77+、Safari 13.1+ 现在支持此功能。
用法与 replace
方法相同:
String.prototype.replaceAll(searchValue, replaceValue)
下面是一个用法示例:
'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'
大多数现代浏览器都支持它,但存在 polyfills:
它在实验标志后面的 V8 发动机中受支持。
在 V8 网站上阅读更多内容。--harmony-string-replaceall
评论
检查这个。我相信它会帮助你:
<!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()
目前它只支持 Babel,但也许将来它可以在所有浏览器中实现。有关更多信息,请阅读此处。
评论
性能
今天 27.12.2019 我在 macOS v10.13.6 (High Sierra) 上对所选解决方案进行测试。
结论
- (C) 是适用于所有字符串的一个很好的跨浏览器快速解决方案。
str.replace(/abc/g, '');
- 基于(A,B)或(C,D)的求解速度很快
split-join
replace
- 基于 (E,F,G,H) 的解速度很慢 - 对于小字符串,通常慢 ~4 倍,对于长字符串,通常慢约 ~3000 倍 (!)
while
- 递归解决方案(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);
详
测试是在Chrome 79.0、Safari 13.0.4和Firefox 71.0(64位)上进行的。测试并使用递归。结果RA
RB
短字符串 - 55 个字符
您可以在此处在计算机上运行测试。Chrome的结果:
长字符串:275 000 个字符
RA 和 RB 给出的递归解
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/860099
function H(str)
{
let i = -1
let 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/860099
function 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/860099
function 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 reccurence
log('RB', RB(t)); // use reccurence
<p style="color:red">This snippet only presents codes used in tests. It not perform test itself!<p>
评论
我们可以在 JavaScript 中使用 replace 方法:
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", "")
}
我在“库”部分的这个性能测试页面中添加了以下函数:
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');
..对我来说,该函数的执行速度比 split 或正则表达式快约 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);
评论
replaceAll
String.prototype.replaceAll
replace
我建议通过将字符串类附加到原型链中来为字符串类添加一个全局方法。
String.prototype.replaceAll = function(fromReplace, toReplace, {ignoreCasing} = {}) { return this.replace(new RegExp(fromReplace, ignoreCasing ? 'ig': 'g'), toReplace);}
它可以像以下方式使用:
'stringwithpattern'.replaceAll('pattern', 'new-pattern')
评论
{ignoreCasing}
this
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
评论
Uncaught TypeError: str.replaceAll is not a function",
regex
该解决方案结合了以前的一些答案,并且更符合建议的 2020 年 8 月标准解决方案。这个解决方案在 2020 年 9 月对我来说仍然可行,因为我使用的 Node.js 二进制文件中不可用。String.replaceAll
RegExp.escape
是一个单独的问题,但在这里很重要,因为官方提出的解决方案将自动转义基于输入。这个 polyfill 不会没有逻辑。string
find
String.replaceAll
RegExp.escape
我添加了一个不 polyfill 的答案,以防您不想要。RegExp.Escape
如果将正则表达式传递给 ,则必须包含为标志。这个 polyfill 不会为你提供一个很好的 TypeError,并且会给你带来一个重大的糟糕时刻。find
g
如果你需要精确的标准一致性,对于一个严格依赖标准实现的应用程序,那么我建议使用 Babel 或其他一些工具来让你每次都能得到“正确的答案”,而不是 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/37
return 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 replace
return 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 replace
return 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)});
评论
Object.prototype.hasOwnProperty.call(String, 'replaceAll')
String.prototype
Object.prototype.hasOwnProperty.call(String.prototype, 'replaceAll')
String.prototype.hasOwnProperty('replaceAll')
有一种方法可以使用新方法。replaceAll()
但是您需要使用尖端的浏览器或 JavaScript 运行时环境。
您可以在此处检查浏览器兼容性。
JavaScript 提供了一种直接的方法,可以将字符串的一部分替换为另一个字符串,并且还有一些技巧可以做到这一点。
替换您可以在 JavaScript 中使用 or 方法的所有匹配项。replace()
replaceAll
replace() method
- 要使用此方法替换所有元素,请使用正则表达式作为模式来查找匹配的字符串,然后将其替换为新字符串。请考虑将标志与它一起使用。/g
const str = "To do or not to do";
const pattern = /do/g;
const replaceBy = "Code";
console.log(str.replace(pattern, replaceBy));
replaceAll() method
- 要使用此方法替换所有元素,请使用字符串或正则表达式作为模式来查找匹配的字符串,然后将其替换为新字符串。我们必须在 replaceAll 方法中使用带有正则表达式的标志。/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, '*');
}
评论
"bc"
"b"
"abcc"
"abc"
"ab"
String.prototype.replaceAll
- ECMAScript 2021
new 方法返回一个新字符串,其中模式的所有匹配项都替换为替换项。模式可以是字符串或 ,替换可以是字符串或要为每个匹配项调用的函数。String.prototype.replaceAll()
RegExp
const message = 'dog barks meow meow';
const messageFormatted = message.replaceAll('meow', 'woof')
console.log(messageFormatted);
评论
replaceAll
已经在近 20 个其他答案和评论中被提出,包括接受的答案和得票最高的答案。这增加了什么?
target
es2021
compilerOptions
tsconfig.json
我已经阅读了这个问题和答案,但我没有找到适合我的解决方案。尽管答案非常有用,但我决定从头开始创建自己的解决方案。这种替换的问题是:
- 通常,仅仅找到一个与任何大写或小写匹配的字符串是不够的。例如,对于搜索结果,我需要将其替换为相同的大小写。
- 如果我处理innerHTML,我很容易损坏HTML标签(例如,href属性中出现hr)。
- replaceAll() 方法对于许多用例来说太新鲜了,它并不能解决所有问题。
因此,我正在编写函数来突出显示表格中的搜索结果,其中表格数据单元格内部可能包含链接以及其他 HTML 标签。而这些链接本来是要保留的,所以innerText是不够的。
我决定为有相同问题的每个人提供解决方案。当然,您不仅可以将其用于表格,还可以将其用于任何元素。代码如下:
/* Iterate over table data cells to insert a highlight tag */
function highlightSearchResults(textFilter) {
textFilter = textFilter.toLowerCase().replace('<', '<').replace('>', '>');
let tds;
tb = document.getElementById('sometable'); //root element where to search
if (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 after
td.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年,正确的答案是:
字符串.prototype.replaceAll()
console.log(
'Change this and this for me'.replaceAll('this','that') // Normal case
);
console.log(
'aaaaaa'.replaceAll('aa','a') // Challenged case
);
但是,如果浏览器是 2020 年之前的呢?
在这种情况下,我们需要 polyfill(强制旧浏览器支持新功能)(我认为几年是必要的)。 我在答案中找不到完全正确的方法。因此,我建议将这个函数定义为 polyfill。
我建议的 polyfill 选项:replaceAll
replaceAll
polyfill(有全局标志错误)(更原则的版本)
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: 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' RegExp
replace); // passing second argument
}
});
}
replaceAll
polyfill (本身缺少处理全局标志) (我的第一偏好) - 为什么?
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: 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' RegExp
replace); // 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
浏览器支持:
- Internet Explorer 9 及更高版本(基于 Internet Explorer 11)。
- 所有其他浏览器(2012 年之后)。
结果与本机 replaceAll 相同,如果第一个参数输入为:、、、、、null
undefined
Object
Function
Date
RegExp
Number
String
参考: 22.1.3.19 String.prototype.replaceAll ( searchValue, replaceValue) + RegExp 语法
重要提示:正如一些专业人士所提到的,答案中建议的许多递归函数将返回错误的结果。(使用上述代码片段的受质疑案例进行尝试。
也许一些棘手的方法,如 .split('searchValue').join('replaceValue')
或一些管理良好的函数给出相同的结果,但性能肯定比native replaceAll()
/ polyfill replaceAll()
/ replace() + RegExp
polyfill 分配的其他方法
幼稚,但支持更旧的浏览器(最好避免)
例如,我们也可以支持 IE7+,不使用 Object.defineProperty() 并使用我以前的朴素赋值方法:
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 年左右。此外,它是一个标准/著名的,因此不需要任何特殊考虑。
但是可能会有更老的浏览器或一些意想不到的问题,polyfills 仍然可以支持和解决更多可能的环境问题。因此,如果我们需要尽可能大的支持,我们可以使用 polyfill 库,例如:
专门用于 replaceAll:
<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>
评论
aba
ababa
ca
caba
abca
cca
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 中发布。来自文档:“如果 searchValue 是一个字符串,则替换所有出现的 searchValue(就好像使用了全局和正确转义的正则表达式一样)。如果 searchValue 是非全局正则表达式,则抛出异常”.split(searchValue).join(replaceValue)
str.replace(/abc/g, '');