Какой самый быстрый способ заменить все экземпляры строки/символа в строке в JavaScript? A while
, for
-loop, регулярное выражение?
Самый быстрый способ заменить все экземпляры символа в строке
Ответ 1
Проще всего было бы использовать регулярное выражение с флагом g
для замены всех экземпляров:
str.replace(/foo/g, "bar")
Это заменит все вхождения foo
на bar
в строке str
. Если у вас есть только строка, вы можете преобразовать ее в объект RegExp следующим образом:
var pattern = "foobar",
re = new RegExp(pattern, "g");
Ответ 2
Попробуйте это 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 теста.
Ответ 3
var mystring = 'This is a string';
var newString = mystring.replace(/i/g, "a");
newString теперь является "Thas as strang"
Ответ 4
Также вы можете попробовать:
string.split('foo').join('bar');
Ответ 5
Вы можете использовать следующее:
newStr = str.replace(/[^a-z0-9]/gi, '_');
или
newStr = str.replace(/[^a-zA-Z0-9]/g, '_');
Это заменит весь символ, который не является буквой или цифрами ('_'). Просто измените значение подчеркивания для того, что вы хотите заменить.
Ответ 6
Просто подумав об этом со скоростью, я считаю, что пример, чувствительный к регистру, приведенный в ссылке выше, будет самым быстрым решением.
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 будет "Это тест системы экстренного вещания".
Ответ 7
Я думаю, что реальный ответ заключается в том, что он полностью зависит от того, как выглядят ваши входы. Я создал JsFiddle, чтобы попробовать кучу этих и пару моих собственных против разных входных данных. Независимо от того, как я смотрю на результаты, я не вижу явного победителя.
- RegExp не был самым быстрым в любом из тестовых случаев, но это было неплохо.
- Подход с разделением/объединением кажется наиболее быстрым для редких замен.
-
Этот, который я написал, кажется самым быстрым для небольших входов и плотных замены:
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; }
Ответ 8
Используйте объект Regex, подобный этому
var regex = new RegExp('"', 'g');
str = str.replace(regex, '\'');
Он заменит все вхождения "
на '
.
Ответ 9
Какой самый быстрый я не знаю, но я знаю, что самое читаемое - самое кратчайшее и самое простое. Даже если это немного медленнее, чем другое решение, которое стоит использовать.
Поэтому используйте:
"string".replace("a", "b");
"string".replace(/abc?/g, "def");
И наслаждайся хорошим кодом, а не быстрее (ну... 1/100000 сек. не разница) и уродливым.;)
Ответ 10
Я пробовал ряд этих предложений после того, как понял, что реализация, которую я написал об этом, вероятно, около 10 лет назад, фактически не сработала полностью (неприятная ошибка производства в давно забытой системе, это не всегда так?!)... я заметил, что те, которые я попробовал (я их не пробовал), имели ту же проблему, что и моя, то есть они не заменяли бы КАЖДОЕ появление, только первое, по крайней мере для моего тестовый пример получения "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;
}
Надеюсь, что это поможет кому-то!
Ответ 11
// 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;
};
Ответ 12
Используйте replace()
метод объекта String
.
Как указано в выбранном ответе, в regex следует использовать флаг /g, чтобы заменить все экземпляры подстроки в строке.
Ответ 13
Я просто закодировал тест и проверил первые 3 ответа.
Похоже, что для коротких строк (& lt; 500 символов)
третий самый голосующий ответ быстрее, чем второй самый голосующий.
Для длинных строк (добавьте ".repeat(300)" к тестовой строке) быстрее ответ 1, за которым следуют вторая и третья.
Примечание:
Вышесказанное относится к браузерам, использующим движок v8 (хром/хром и т.д.).
С Firefox (движок SpiderMonkey) результаты совершенно разные
Проверьте сами! Firefox с третьим решением кажется
более чем в 4,5 раза быстрее, чем Chrome с первым решением... сумасшедший: 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>
Ответ 14
@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)