Источник: Stack Overflow
В этот раз разберёмся, как можно заменить все одинаковые подстроки в конкретной строке. Допустим, у нас есть строчка:
var str = "Test abc test test abc test test test abc test test abc";
А наш код должен заменить, например, все подстроки abc
в этой строке. Использовать метод replace
не получится, ведь так мы заменим лишь самую первую подстроку abc
.
Существует как минимум два оптимальных решения этой задачи: использование регулярных выражений и методов split
и join
.
Внимание: в приведённых ниже примерах мы решим данную задачу, переписывая встроенные в JavaScript методы. Это не самая лучшая практика и настоятельно не рекомендуется к использованию в реальных проектах. Мы же будем использовать её исключительно в демонстрационных целях.
Метод первый — регулярные выражения
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
Метод второй — split и join
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
Что касается производительности, то стоит отметить, что первое решение работает аж в два раза быстрее второго.
Однако существует загвоздка в решении с использованием регулярных выражений: предполагается, что пользователь не будет использовать зарезервированные для регулярных выражений символы в качестве первого параметра. Пользователи бывают разные и зачастую совершают не самые разумные поступки с нашими творениями, так что не будем рисковать и предотвратим этот вариант развития событий.
Нам нужна функция, которая будет форматировать аргумент search:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
Всё, что остаётся, — вызвать функцию escapeRegExp
в нашем String.prototype.replaceAll
:
String.prototype.replaceAll = function(search, replacement) {
search = escapeRegExp(search);
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};