НейроАгент

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

Узнайте, как заменить все вхождения строки в JavaScript с помощью метода replaceAll() или регулярных выражений. Полное руководство с примерами и информацией о совместимости браузеров.

Вопрос

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

Дана строка:

javascript
string = "Test abc test test abc test test test abc test test abc";

Базовый метод replace() удаляет только первое вхождение “abc” в приведенной выше строке:

javascript
string = string.replace('abc', '');

Как можно заменить ВСЕ вхождения “abc” в строке?

НейроАгент

Чтобы заменить все вхождения строки в JavaScript, можно использовать либо современный метод replaceAll(), либо традиционный подход с replace() в сочетании с регулярным выражением, использующим глобальный флаг (/g). Метод replaceAll() является самым простым решением, в то время как подход с регулярными выражениями работает в более старых версиях браузеров.


Содержание


Проблема с методом replace()

Базовый метод replace() в JavaScript заменяет только первое вхождение подстроки, как вы, возможно, заметили:

javascript
const string = "Test abc test test abc test test test abc test test abc";
const result = string.replace('abc', '');
console.log(result);
// Вывод: "Test  test test abc test test test abc test test abc"

Это ограничение давно является источником путаницы для разработчиков JavaScript [источник]. Метод replace() был разработан для замены только первого совпадения при использовании строкового шаблона, если вы не укажете иное [источник].


Метод 1: Использование replaceAll()

Метод replaceAll() является современным и простым решением для замены всех вхождений подстроки [источник].

Базовое использование

javascript
const string = "Test abc test test abc test test test abc test test abc";
const result = string.replaceAll('abc', '');
console.log(result);
// Вывод: "Test  test test  test test test  test test "

Ключевые особенности

  • Глобальная замена по умолчанию: При использовании строкового шаблона replaceAll() автоматически заменяет все вхождения [источник]
  • Гибкие типы шаблонов: Принимает как строки, так и регулярные выражения в качестве шаблонов
  • Поддержка функций: Может принимать функцию замены для динамической замены
  • Неизменяемая операция: Возвращает новую строку без изменения исходной [источник]

С регулярными выражениями

При использовании регулярных выражений с replaceAll() вы обязаны включить глобальный флаг (/g), в противном случае будет выброшена ошибка TypeError [источник]:

javascript
// Правильное использование с глобальным флагом
const result = string.replaceAll(/abc/g, '');

// Это вызовет ошибку:
// TypeError: replaceAll must be called with a global RegExp
const errorResult = string.replaceAll(/abc/, '');

Метод 2: Использование replace() с глобальным регулярным выражением

Для сред, которые не поддерживают replaceAll(), можно использовать традиционный подход с replace() и регулярным выражением с глобальным флагом [источник].

Базовое использование

javascript
const string = "Test abc test test abc test test test abc test test abc";
const result = string.replace(/abc/g, '');
console.log(result);
// Вывод: "Test  test test  test test test  test test "

Ключевые особенности

  • Универсальная совместимость: Работает во всех средах JavaScript
  • Явный глобальный флаг: Четкое указание намерений с флагом /g
  • Та же функциональность: Идентичные результаты с replaceAll() при правильном использовании

Почему требуется флаг /g

Глобальный флаг (/g) указывает движку регулярных выражений находить все совпадения в строке, а не останавливаться после первого совпадения [источник]. Без него метод replace() будет вести себя точно так же, как базовый метод замены строки.


Метод 3: Альтернативные подходы

Метод разделения и соединения

Также можно добиться глобальной замены, разделив строку и соединив ее с заменой [источник]:

javascript
const string = "Test abc test test abc test test test abc test test abc";
const result = string.split('abc').join('');
console.log(result);
// Вывод: "Test  test test  test test test  test test "

Когда использовать этот метод

  • Очень простые шаблоны: Хорошо работает для простой замены подстроки
  • Отсутствие сложности с регулярными выражениями: Избегает синтаксиса регулярных выражений
  • Устаревшие среды: Работает в очень старых средах JavaScript

Однако этот метод обычно менее эффективен, чем подходы на основе регулярных выражений [источник].


Сравнение производительности

Результаты тестирования

Согласно различным тестам производительности [источник][источник]:

  1. replaceAll() и replace() с регулярными выражениями показывают незначительные различия в производительности
  2. Метод разделения и соединения обычно медленнее в большинстве случаев использования
  3. Разница в производительности становится заметной только при очень больших строках (10 000+ символов)

Пример производительности

javascript
// Большая строка для тестирования производительности
const largeString = 'abc'.repeat(10000);
const startTime = performance.now();

// Тест replaceAll
const result1 = largeString.replaceAll('abc', 'xyz');
const endTime1 = performance.now();

// Тест replace с регулярным выражением
const result2 = largeString.replace(/abc/g, 'xyz');
const endTime2 = performance.now();

console.log(`replaceAll: ${endTime1 - startTime}мс`);
console.log(`regex replace: ${endTime2 - endTime1}мс`);

“Скоростная разница между ними незначительна. Вы должны обрабатывать большие строки, прежде чем даже приблизиться к разнице в скорости 0,01 миллисекунды.” [источник]


Совместимость с браузерами

Поддержка replaceAll()

Метод replaceAll() поддерживается в:

  • Chrome 85+ (август 2020)
  • Firefox 77+ (июнь 2020)
  • Safari 13.1+ (март 2020)
  • Edge 85+ (август 2020) [источник]

Полифилл для старых браузеров

Если вам нужно поддерживать старые браузеры, можно добавить полифилл [источник]:

javascript
if (!String.prototype.replaceAll) {
  String.prototype.replaceAll = function(pattern, replacement) {
    return this.replace(new RegExp(pattern, 'g'), replacement);
  };
}

Обнаружение возможностей

Всегда проверяйте доступность метода перед его использованием [источник]:

javascript
if (typeof String.prototype.replaceAll === 'function') {
  // Используем replaceAll
  return string.replaceAll('abc', '');
} else {
  // Возвращаемся к replace с регулярным выражением
  return string.replace(/abc/g, '');
}

Практические примеры

Пример 1: Простая замена текста

javascript
const text = "Быстрая коричневая лиса прыгает через ленивую собаку. Лиса была очень быстрой.";
const result = text.replaceAll('лиса', 'кошка');
console.log(result);
// Вывод: "Быстрая коричневая кошка прыгает через ленивую собаку. Кошка была очень быстрой."

Пример 2: Замена без учета регистра

javascript
const text = "ABC abc ABC abc";
const result = text.replace(/abc/gi, '');
console.log(result);
// Вывод: "    "

Пример 3: Использование функции замены

javascript
const text = "а1 б2 в3 г4";
const result = text.replace(/\d/g, (match) => {
  return parseInt(match) * 2;
});
console.log(result);
// Вывод: "а2 б4 в6 г8"

Пример 4: Несколько разных замен

javascript
const text = "Привет мир, привет JavaScript, привет программирование";
const result = text.replace(/привет/gi, 'Привет');
console.log(result);
// Вывод: "Привет мир, Привет JavaScript, Привет программирование"

Лучшие практики

1. Выберите правильный метод

  • Используйте replaceAll(): Для современных кодовых баз и максимальной читаемости
  • Используйте replace() с регулярными выражениями: Для поддержки старых браузеров или когда нужны возможности регулярных выражений
  • Используйте разделение/соединение: Для очень простых случаев, когда регулярные выражения не нужны

2. Всегда тестируйте граничные случаи

javascript
// Тестируем пустые строки
const emptyResult = "abc".replaceAll('abc', ''); // Работает нормально
const emptyResult2 = "".replaceAll('abc', '');   // Также работает

// Тестируем отсутствие совпадений
const noMatch = "hello".replaceAll('abc', 'xyz'); // Возвращает исходную строку

3. Учитывайте производительность для больших строк

javascript
// Для очень больших строк учитывайте производительность
function safeReplaceAll(str, pattern, replacement) {
  if (str.length > 10000) {
    return str.split(pattern).join(replacement);
  }
  return str.replaceAll(pattern, replacement);
}

4. Документируйте свой выбор

javascript
/**
 * Заменяет все вхождения подстроки в строке.
 * Использует replaceAll() для современных браузеров, переходит к replace с регулярным выражением для совместимости.
 */
function globalReplace(str, search, replace) {
  if (typeof String.prototype.replaceAll === 'function') {
    return str.replaceAll(search, replace);
  }
  return str.replace(new RegExp(search, 'g'), replace);
}

Заключение

Замена всех вхождений строки в JavaScript становится простой задачей, как только вы понимаете доступные методы:

  1. Современный подход: Используйте replaceAll() для чистого, читаемого кода, который автоматически обрабатывает глобальную замену
  2. Традиционный подход: Используйте replace() с флагом /g для максимальной совместимости с браузерами
  3. Простые случаи: Рассмотрите разделение/соединение для очень базальных потребностей в замене

Метод replaceAll() теперь широко поддерживается во всех основных браузерах и должен быть вашим выбором по умолчанию для новых проектов [источник]. Для устаревших кодовых баз подход с регулярными выражениями предоставляет эквивалентную функциональность с более широкой совместимостью.

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


Источники

  1. String.prototype.replaceAll() - JavaScript | MDN
  2. How do I replace all occurrences of a string? - Stack Overflow
  3. 3 Ways To Replace All String Occurrences in JavaScript - Dmitri Pavlutin
  4. How to replace all occurrences of a string in JavaScript? - CoreUI
  5. String.prototype.replaceAll · V8
  6. JavaScript replaceAll() – Replace All Instances of a String in JS - freeCodeCamp
  7. Benchmark: replaceAll vs regex replace - MeasureThat.net
  8. Replace vs Replace All Comparison - Alexander Karan