Как заменить все вхождения строки

javascript string replace


У меня есть эта веревка:

"Test abc test test abc test test test abc test test abc"

Doing:

str = str.replace('abc', '');

кажется, только удалить первое вхождение abc в строке выше.

Как я могу заменить все вхождения этого?




Answer 1 Matthew Crumley


Примечание: не используйте это в коде, критичном к производительности.

В качестве альтернативы регулярным выражениям для простой литературной строки,можно использовать следующие слова

str = "Test abc test test abc test...".split("abc").join("");

Общая закономерность заключается в том,что

str.split(search).join(replacement)

Раньше в некоторых случаях это происходило быстрее, чем использование replaceAll и регулярного выражения, но в современных браузерах это больше не так.

Тест: https://jsperf.com/replace-all-vs-split-join

Вывод:Если у вас критический сценарий использования (например,обработка сотен строк),используйте метод Regexp.Но в большинстве типичных случаев использования этого метода не стоит беспокоиться о специальных символах.




Answer 2 Sean Bright


str = str.replace(/abc/g, '');

В ответ на комментарий:

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);
}

Примечание. Регулярные выражения содержат специальные (мета) символы, и поэтому опасно слепо передавать аргумент в функции find выше без предварительной обработки для экранирования этих символов. Это описано в Mozilla Developer Network «s Guide JavaScript на регулярных выражениях , где они представляют следующую функцию полезности (которая изменилась , по крайней мере в два раза , так как этот ответ был изначально написано, так что не забудьте проверить сайт MDN для потенциальных обновлений):

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);
}



Answer 3 Cory Gross


Для полноты,я должен подумать о том,какой метод я должен использовать для этого.В принципе,есть два способа сделать это,как предлагают другие ответы на этой странице.

Примечание. Как правило, расширение встроенных прототипов в 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 и других, может быть проблема с реализацией на основе регулярных выражений, если search содержит определенные символы, которые зарезервированы как специальные символы в регулярных выражениях . Реализация предполагает, что вызывающая сторона будет избегать строки заранее или будет передавать только те строки, которые не имеют символов в таблице в регулярных выражениях (MDN).

MDN также предоставляет реализацию, позволяющую избежать наших строк. Было бы хорошо, если бы это было также стандартизировано как RegExp.escape(str) , но, увы, его не существует:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

Мы могли бы вызвать escapeRegExp в нашей реализации String.prototype.replaceAll , однако я не уверен, насколько это повлияет на производительность (потенциально даже для строк, для которых экранирование не требуется, как для всех буквенно-цифровых строк).




Answer 4 Adam A


Использование регулярного выражения с установленным флагом g заменит все:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

См.также здесь




Answer 5 jesal


Вот прототип строковой функции,основанной на принятом ответе:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

EDIT

Если ваша find будет содержать специальные символы, вам нужно их избежать:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

Скрипка: http://jsfiddle.net/cdbzL/