在JavaScript中替换字符串/字符的所有实例的最快方法是什么?while, for循环,正则表达式?
当前回答
// 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 Leftover
if(s.length>0){ r+=o.substring(o.length-s.length, o.length); }
// Return New String
return r;
};
其他回答
你可以使用以下方法:
newStr = str.replace(/[^a-z0-9]/gi, '_');
or
newStr = str.replace(/[^a-zA-Z0-9]/g, '_');
这将替换所有不是字母或数字的字符('_')。简单地更改下划线值的任何你想替换它。
I tried a number of these suggestions after realizing that an implementation I had written of this probably close to 10 years ago actually didn't work completely (nasty production bug in an long-forgotten system, isn't that always the way?!)... what I noticed is that the ones I tried (I didn't try them all) had the same problem as mine, that is, they wouldn't replace EVERY occurrence, only the first, at least for my test case of getting "test....txt" down to "test.txt" by replacing ".." with "."... maybe I missed so regex situation? But I digress...
因此,我重写了我的实现如下。这是非常简单的,虽然我怀疑不是最快的,但我也不认为现代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;
}
希望这能帮助到别人!
我只是编写了一个基准测试,并测试了前3个答案。 对于短字符串(<500字符) 投票第三多的答案比投票第二多的答案快。
对于长字符串(在测试字符串中添加".repeat(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 Leftover if(s.length>0){ r+=o.substring(o.length-s.length, o.length); } // Return New String return 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>
当您单击按钮时,测试将运行10s (+2s)。
我的结果(在同一台电脑上):
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 64
1. 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 10
1. 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 10
1. 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 10
1. 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)
Galaxy Note 4上的Chrome
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)
试试这个replaceAll: 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);
}
这是非常快的,它将工作在所有这些条件 很多人都没有做到的:
"x".replaceAll("x", "xyz");
// xyz
"x".replaceAll("", "xyz");
// xyzxxyz
"aA".replaceAll("a", "b", true);
// bb
"Hello???".replaceAll("?", "!");
// Hello!!!
让我知道你是否可以打破它,或者你有更好的东西,但要确保它能通过这4个测试。
最简单的方法是使用带有g标志的正则表达式来替换所有实例:
str.replace(/foo/g, "bar")
这将把字符串str中出现的所有foo替换为bar。如果你只有一个字符串,你可以像这样将它转换为RegExp对象:
var pattern = "foobar",
re = new RegExp(pattern, "g");
推荐文章
- 为时刻添加持续时间(moment.js)
- 如何在JavaScript中获得时区名称?
- 在JSON键名中哪些字符是有效的/无效的?
- jQuery中的live()转换为on()
- 如何区分鼠标的“点击”和“拖动”
- IE9是否支持console.log,它是一个真实的功能吗?
- Node.js同步执行系统命令
- 如何转义JSON字符串包含换行字符使用JavaScript?
- jQuery等价于JavaScript的addEventListener方法
- jQuery需要避免的陷阱
- JavaScript中变量字符串的XML解析
- 我如何在c++中创建一个随机的字母数字字符串?
- 'React'指的是一个UMD全局,但当前文件是一个模块
- 为什么useState不触发重新渲染?
- 如何使用回调与useState挂钩在反应