在JavaScript中,替换字符串/字符的所有实例的最快方法是什么?使用 while
循环、for
循环还是正则表达式?
在JavaScript中,替换字符串/字符的所有实例的最快方法是什么?使用 while
循环、for
循环还是正则表达式?
最简单的方法是使用带有 g
标志的正则表达式来替换所有实例:
str.replace(/foo/g, "bar")
这将替换字符串str
中所有出现的foo
为bar
。如果你只有一个字符串,你可以像下面这样将其转换为RegExp对象:
var pattern = "foobar",
re = new RegExp(pattern, "g");
user.email.replace(/./g,',')
,整个电子邮件中的字符都被逗号替换,替换次数等于电子邮件字符数。感到困惑... - Jared Tomaszewski尝试使用replaceAll函数:
http://dumpsite.com/forum/index.php?topic=4.msg8#msg8String.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个测试。
var mystring = 'This is a string';
var newString = mystring.replace(/i/g, "a");
newString现在是'Thas as a strang'
也可以尝试以下方法:
string.split('foo').join('bar');
"12px (2) bar-456-foo 44".split(/\d/).join("#")
- Vladafunction replaceAll( s, f, r ){ return s.split( f ).join( r ); }
。或者如果您认为正则表达式更快:function replaceAll( s, f, r ){ f = RegExp( f, 'gi' ); return s.replace( f, r ); }
。然后只需执行 foo = replaceAll( 'aaa', 'a', 'b' );
。 - BeejornewStr = str.replace(/[^a-z0-9]/gi, '_');
或者
newStr = str.replace(/[^a-zA-Z0-9]/g, '_');
使用正则表达式对象的方式如下:
var regex = new RegExp('"', 'g');
str = str.replace(regex, '\'');
它将把所有出现的 "
替换成 '
。
我认为真正的答案完全取决于你的输入是什么样子。我创建了一个 JsFiddle 来尝试一些这些方法和我的一些方法来处理各种输入。无论如何,我都没有看到明显的获胜者。
我写的这个似乎是处理小输入和密集替换最快的:
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 match
break;
}
compareIndex++; replaceIndex++;
if(i >= sourceLength){
// not a match
break;
}
sourceCompareCharacter = inSource.charAt(compareIndex)
replaceCompareCharacter = inToReplace.charAt(replaceIndex);
}
replaceCompareCharacter += currentCharacter;
}
return output;
}
仅从速度问题考虑,我相信上面链接提供的区分大小写的示例将是迄今为止最快的解决方案。
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将是"This is a test of the emergency broadcast system."
我刚编写了一个基准测试并测试了前三个答案。对于短字符串(<500字符),第三个最受欢迎的答案似乎比第二个更快。
对于长字符串(将“.repeat(300)”添加到测试字符串中),速度最快的是第一种解决方案,其次是第二种和第三种。
注意:
以上内容适用于使用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>
当你点击按钮时,测试将持续10秒(+2秒)。
我的结果(在同一台电脑上):
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)
最快的方法我不知道,但我知道最易读的方法是最短和最简单的。即使它比其他解决方案慢一点,也值得使用。
因此,请使用以下内容:
"string".replace("a", "b");
"string".replace(/abc?/g, "def");
replace
何时被优化,但是split
-join
现在变慢了40%以上。 - Chiramisu