替换字符串中字符的所有实例的最快方法

在JavaScript中替换字符串/字符中所有字符串/字符实例的最快方法是什么?whilefor循环、正则表达式?

956361 次浏览

使用String对象的replace()方法。

正如所选答案中提到的, /g标志应该在regex中使用,以便替换字符串中子字符串的所有实例。

var mystring = 'This is a string';var newString = mystring.replace(/i/g, "a");

newString现在是'Thas as a String'

什么是最快的我不知道,但我知道什么是最可读的-什么是最短和最简单的。即使它比其他解决方案慢一点,也值得使用。

所以使用:

 "string".replace("a", "b");"string".replace(/abc?/g, "def");

享受好的代码,而不是更快(好吧……1/100000秒。没有区别)和丑陋的。;)

最简单的方法是使用带有g标志的正则表达式来替换所有实例:

str.replace(/foo/g, "bar")

这将在字符串str中用bar替换所有出现的foo。如果你只有一个字符串,你可以像这样将它转换为RegExp对象:

var pattern = "foobar",re = new RegExp(pattern, "g");

试试这个替换全部:http://dumpsite.com/forum/index.php?topic=4.msg8#msg8

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

它非常快,它将适用于所有这些条件#36825;很多人都不满意:

"x".replaceAll("x", "xyz");// xyz
"x".replaceAll("", "xyz");// xyzxxyz
"aA".replaceAll("a", "b", true);// bb
"Hello???".replaceAll("?", "!");// Hello!!!

让我知道你是否能打破它,或者你有更好的东西,但要确保它能通过这4个测试。

我尝试了许多这些建议,因为我意识到我写的一个实现可能接近10年前实际上并没有完全工作(讨厌的生产bug在一个长期被遗忘的系统中,不总是这样吗?!)…我注意到我尝试的那些(我没有全部尝试)和我的有同样的问题,也就是说,它们不会替换每一个出现,只有第一个,至少对于我的测试用例来说,通过将“…”替换为“…”来获取“test… txt”到“test.txt”。

所以,我重写了我的实现如下。它非常简单,虽然我怀疑不是最快的,但我也不认为现代JS引擎的差异会有关系,除非你在一个紧密的循环中这样做,但这总是任何事情的情况……

function replaceSubstring(inSource, inToReplace, inReplaceWith) {
var outString = inSource;while (true) {var idx = outString.indexOf(inToReplace);if (idx == -1) {break;}outString = outString.substring(0, idx) + inReplaceWith +outString.substring(idx + inToReplace.length);}return outString;
}

希望能帮助到别人!

您可以使用以下内容:

newStr = str.replace(/[^a-z0-9]/gi, '_');

newStr = str.replace(/[^a-zA-Z0-9]/g, '_');

这将把所有不是字母或数字的字符替换为('_')。简单地更改您想要替换它的下划线值。

像这样使用Regex对象

var regex=new RegExp('"', 'g');str=str.replace(正则表达式, '\'');

它会将所有出现的"替换为'

从速度问题上考虑一下,我相信上面链接中提供的区分大小写的示例将是迄今为止最快的解决方案。

var token = "\r\n";var newToken = " ";var oldStr = "This is a test\r\nof the emergency broadcasting\r\nsystem.";newStr = oldStr.split(token).join(newToken);

newStr是“这是对紧急广播系统的测试。”

// Find, Replace, Case// i.e "Test to see if this works? (Yes|No)".replaceAll('(Yes|No)', 'Yes!');// i.e.2 "Test to see if this works? (Yes|No)".replaceAll('(yes|no)', 'Yes!', true);String.prototype.replaceAll = function(_f, _r, _c){
var o = this.toString();var r = '';var s = o;var b = 0;var e = -1;if(_c){ _f = _f.toLowerCase(); s = o.toLowerCase(); }
while((e=s.indexOf(_f)) > -1){r += o.substring(b, b+e) + _r;s = s.substring(e+_f.length, s.length);b += e+_f.length;}
// Add Leftoverif(s.length>0){ r+=o.substring(o.length-s.length, o.length); }
// Return New Stringreturn r;};

你也可以试试:

string.split('foo').join('bar');

我认为真正的答案是,这完全取决于你的输入是什么样子。我创建了一个JsFiddle来尝试一堆这些和我自己的几个对各种输入。无论我如何看待结果,我都看不到明确的赢家。

  • RegExp在任何测试用例中都不是最快的,但它也不坏。
  • 对于稀疏替换,Split/Join方法似乎最快。
  • 我写的这个对于小输入和密集来说似乎最快替换:

    function replaceAllOneCharAtATime(inSource, inToReplace, inReplaceWith) {var output="";var firstReplaceCompareCharacter = inToReplace.charAt(0);var sourceLength = inSource.length;var replaceLengthMinusOne = inToReplace.length - 1;for(var i = 0; i < sourceLength; i++){var currentCharacter = inSource.charAt(i);var compareIndex = i;var replaceIndex = 0;var sourceCompareCharacter = currentCharacter;var replaceCompareCharacter = firstReplaceCompareCharacter;while(true){if(sourceCompareCharacter != replaceCompareCharacter){output += currentCharacter;break;}if(replaceIndex >= replaceLengthMinusOne) {i+=replaceLengthMinusOne;output += inReplaceWith;//was a matchbreak;}compareIndex++; replaceIndex++;if(i >= sourceLength){// not a matchbreak;}sourceCompareCharacter = inSource.charAt(compareIndex)replaceCompareCharacter = inToReplace.charAt(replaceIndex);}replaceCompareCharacter += currentCharacter;}return output;}

@Gumbo添加额外的答案-user.email.replace(/foo/gi,"bar");

/foo/g - Refers to the all string to replace matching the case sensitive
/foo/gi - Refers to the without case sensitive and replace all For Eg: (Foo, foo, FoO, fOO)

演示

我刚刚编写了一个基准测试并测试了前3个答案。似乎对于短字符串(<500个字符)
第三个投票最多的答案比第二个投票最多的答案更快。

对于长字符串(在测试字符串中添加“.重复(300)”),更快的是答案1,其次是第二个和第三个。

备注:

以上对于使用v8引擎(chrome/chromium等)的浏览器是正确的。
使用Firefox(SpiderMonkey引擎),结果完全不同
自己检查!!!第三种解决方案的Firefox似乎是
比第一个解决方案的Chrome快4.5倍以上……疯狂:D

function log(data) {document.getElementById("log").textContent += data + "\n";}
benchmark = (() => {
time_function = function(ms, f, num) {var z;var t = new Date().getTime();for (z = 0;((new Date().getTime() - t) < ms); z++) f(num);return (z / ms)} // returns how many times the function was run in "ms" milliseconds.

function benchmark() {function compare(a, b) {if (a[1] > b[1]) {return -1;}if (a[1] < b[1]) {return 1;}return 0;}
// functions
function replace1(s) {s.replace(/foo/g, "bar")}
String.prototype.replaceAll2 = function(_f, _r){
var o = this.toString();var r = '';var s = o;var b = 0;var e = -1;//      if(_c){ _f = _f.toLowerCase(); s = o.toLowerCase(); }
while((e=s.indexOf(_f)) > -1){r += o.substring(b, b+e) + _r;s = s.substring(e+_f.length, s.length);b += e+_f.length;}
// Add Leftoverif(s.length>0){ r+=o.substring(o.length-s.length, o.length); }
// Return New Stringreturn r;};
String.prototype.replaceAll = function(str1, str2, ignore) {return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, "\\$&"), (ignore ? "gi" : "g")), (typeof(str2) == "string") ? str2.replace(/\$/g, "$$$$") : str2);}
function replace2(s) {s.replaceAll("foo", "bar")}
function replace3(s) {s.split('foo').join('bar');}
function replace4(s) {s.replaceAll2("foo", "bar")}

funcs = [[replace1, 0],[replace2, 0],[replace3, 0],[replace4, 0]];
funcs.forEach((ff) => {console.log("Benchmarking: " + ff[0].name);ff[1] = time_function(2500, ff[0], "foOfoobarBaR barbarfoobarf00".repeat(10));console.log("Score: " + ff[1]);
})return funcs.sort(compare);}
return benchmark;})()log("Starting benchmark...\n");res = benchmark();console.log("Winner: " + res[0][0].name + " !!!");count = 1;res.forEach((r) => {log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");});log("\nWinner code:\n");log(res[0][0].toString());
<textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>

The test will run for 10s (+2s) as you click the button.

My results (on the same pc):

Chrome/Linux Ubuntu 64:1. replace1 score: 100% *winner* (766.18)2. replace4 score: 99.07% speed of winner. (759.11)3. replace3 score: 68.36% speed of winner. (523.83)4. replace2 score: 59.35% speed of winner. (454.78)
Firefox/Linux Ubuntu 641. replace3 score: 100% *winner* (3480.1)2. replace1 score: 13.06% speed of winner. (454.83)3. replace4 score: 9.4% speed of winner. (327.42)4. replace2 score: 4.81% speed of winner. (167.46)

一团糟不错啊?

擅自添加了更多的测试结果

Chrome/Windows 101. replace1 score: 100% *winner* (742.49)2. replace4 score: 85.58% speed of winner. (635.44)3. replace2 score: 54.42% speed of winner. (404.08)4. replace3 score: 50.06% speed of winner. (371.73)
Firefox/Windows 101. replace3 score: 100% *winner* (2645.18)2. replace1 score: 30.77% speed of winner. (814.18)3. replace4 score: 22.3% speed of winner. (589.97)4. replace2 score: 12.51% speed of winner. (331.13)
Edge/Windows 101. replace1 score: 100% *winner* (1251.24)2. replace2 score: 46.63% speed of winner. (583.47)3. replace3 score: 44.42% speed of winner. (555.92)4. replace4 score: 20% speed of winner. (250.28)

ChromeGalaxy Note 4

1. replace4 score: 100% *winner* (99.82)2. replace1 score: 91.04% speed of winner. (90.88)3. replace3 score: 70.27% speed of winner. (70.15)4. replace2 score: 38.25% speed of winner. (38.18)