ReplaceAll: примеры (JAVASCRIPT)

Руководство по работе с replaceAll в JavaScript
Раздел: Строки, Замена
replaceAll(pattern, replacement): string

Метод replaceAll в JavaScript

Метод replaceAll() является встроенным методом объектов типа String. Его основное назначение — возвращать новую строку, в которой все совпадения с заданным шаблоном заменены на указанную строку-заменитель. Первоначальная строка при этом не изменяется.

Использование метода актуально при необходимости глобальной замены всех вхождений подстроки, например, при санации пользовательского ввода, форматировании текста или обработке шаблонов.

Аргументы метода

Метод принимает два аргумента:

  1. pattern (шаблон): Может быть строкой или объектом RegExp (регулярным выражением).
    • Если передана строка, будет выполнена замена всех её точных вхождений.
    • Если передано регулярное выражение, оно обязательно должно содержать флаг глобального поиска g, иначе будет выброшена ошибка TypeError.
  2. replacement (замена): Может быть строкой или функцией.
    • Строка: Заменяет каждое найденное совпадение. В строке-заменителе можно использовать специальные паттерны, например, $& для вставки всего совпадения, $` для части строки до совпадения, $' для части строки после совпадения, $n для n-й захватывающей группы регулярного выражения.
    • Функция: Вызывается для каждого совпадения. Результат её выполнения (строка) используется в качестве замены. Функция получает аргументы: match (совпадение), p1, p2, ..., pn (захваченные группы), offset (индекс совпадения), string (исходная строка).

Возвращаемое значение

Метод всегда возвращает новую строку, являющуюся результатом всех выполненных замен. Исходная строка остаётся неизменной.

Примеры базового использования

Простая замена одной строки на другую:

let text = 'Собака бежала за собакой.';
let result = text.replaceAll('собака', 'кошкой');
console.log(result);
// Результат: Собака бежала за кошкой.

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

let text = 'Собака бежала за собакой.';
let result = text.replaceAll(/собака/gi, 'котом');
console.log(result);
// Результат: котом бежала за котом.

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

let str = 'Цены: 100, 200, 300';
let newStr = str.replaceAll(/\d+/g, (match) => parseInt(match) * 1.1);
console.log(newStr);
// Результат: Цены: 110, 220, 330

Альтернативные методы в JavaScript

  • String.prototype.replace(): Ближайший аналог. Если первому аргументу передать строку, заменяется только первое вхождение. Для глобальной замены необходимо использовать регулярное выражение с флагом g. Метод replaceAll() был введён для более интуитивной глобальной замены при передаче строки в качестве шаблона.
  • Комбинация split() и join(): str.split(search).join(replacement) даёт аналогичный replaceAll результат для строкового шаблона. Этот способ часто использовался до появления replaceAll.
  • Глобальное регулярное выражение: str.replace(/pattern/g, replacement) — классический способ, который работает идентично replaceAll с регулярным выражением.

Когда что использовать: replaceAll() предпочтителен для простой и понятной глобальной замены подстроки. Метод replace() остаётся универсальным инструментом, особенно когда нужна замена только первого вхождения или сложная логика с использованием функций. Комбинация split/join теперь считается устаревшим обходным путём.

Распространённые ошибки

1. Передача регулярного выражения без флага 'g'. Это вызывает ошибку TypeError для обеспечения ясного поведения, отличного от replace().

try {
    let result = 'aaa'.replaceAll(/a/, 'b');
} catch (e) {
    console.log(e.toString()); // TypeError: String.prototype.replaceAll called with a non-global RegExp argument
}
// Результат: TypeError: String.prototype.replaceAll called with a non-global RegExp argument

2. Некорректное экранирование специальных символов в строке-шаблоне при использовании регулярного выражения.

// Цель: заменить точку '.' на '!'
let str = 'a.b.c';
// Ошибка: точка в regex - любой символ
let wrongResult = str.replaceAll(/./g, '!');
console.log(wrongResult); // Полностью изменит строку!
// Правильно: экранировать
let correctResult = str.replaceAll(/\./g, '!');
console.log(correctResult);
// Результат wrongResult: !!!!!
// Результат correctResult: a!b!c

3. Забывают, что метод возвращает новую строку, а не изменяет исходную.

let original = "Hello world";
let modified = original.replaceAll("world", "JavaScript");
console.log(original); // Остаётся "Hello world"
console.log(modified); // "Hello JavaScript"

Изменения и история

Метод replaceAll был официально добавлен в спецификацию ECMAScript 2021 (ES12). До этого разработчики использовали либо replace() с глобальным регулярным выражением (/pattern/g), либо комбинацию split() и join() для строковых шаблонов. Введение replaceAll устранило необходимость в этих обходных путях, сделав код для глобальной замены строк более читаемым и прямолинейным. С момента добавления метод поддерживается во всех современных браузерах и средах выполнения Node.js.

Расширенные примеры применения

Использование специальных паттернов замены в строке:

Пример javascript
let text = "abc123def";
// Вставляет символ '-' до и после каждой цифры
let result = text.replaceAll(/\d/g, "-$&-");
console.log(result);
// Результат: abc-1--2--3-def

Одновременная замена нескольких разных подстрок с помощью массива:

Пример javascript
let str = "Я люблю яблоки и бананы";
let replacements = [["яблоки", "апельсины"], ["бананы", "клубнику"]];
for (let [search, repl] of replacements) {
    str = str.replaceAll(search, repl);
}
console.log(str);
// Результат: Я люблю апельсины и клубнику

Замена с использованием захватывающих групп в регулярном выражении:

Пример javascript
let names = "Иванов Пётр, Сидоров Василий";
// Меняем местами фамилию и имя
let swapped = names.replaceAll(/(\w+)\s+(\w+)/g, "$2 $1");
console.log(swapped);
// Результат: Пётр Иванов, Василий Сидоров

Санитизация HTML-строк (упрощённый пример):

Пример javascript
let userInput = "<script>alert('xss')</script><p>Текст</p>";
let safeHtml = userInput.replaceAll(/&/g, "&")
                         .replaceAll(//g, ">")
                         .replaceAll(/"/g, """);
console.log(safeHtml);
// Результат: &lt;script&gt;alert('xss')&lt;/script&gt;&lt;p&gt;Текст&lt;/p&gt;

Рекурсивная замена в многоуровневом шаблоне:

Пример javascript
function renderTemplate(template, data) {
    let result = template;
    // Заменяем все вхождения каждого ключа из data
    for (let key in data) {
        let placeholder = new RegExp(`{{${key}}}`, 'g'); // Динамическое создание regex с флагом 'g'
        result = result.replaceAll(placeholder, data[key]);
    }
    return result;
}
let tmpl = "{{name}} работает в {{company}}. Email: {{email}}";
let userData = {name: "Анна", company: "IT-фирма", email: "anna@example.com"};
console.log(renderTemplate(tmpl, userData));
// Результат: Анна работает в IT-фирма. Email: anna@example.com

Аналоги в других языках программирования

PHP: Функция str_replace() по умолчанию заменяет все вхождения. Её аргументы — массив или строка для поиска и массив или строка для замены.

$text = "apple, apple, pear";
$result = str_replace("apple", "orange", $text);
echo $result;
// Результат: orange, orange, pear

Python: Метод строки str.replace(old, new[, count]). Аргумент count опционален и указывает количество замен (по умолчанию — все).

text = "apple, apple, pear"
result = text.replace("apple", "orange")
print(result)
// Результат: orange, orange, pear

MySQL: Функция REPLACE(str, from_str, to_str) заменяет все вхождения подстроки в строке.

SELECT REPLACE('apple, apple, pear', 'apple', 'orange');
/* Результат: orange, orange, pear */

C (стандартная библиотека): Прямого аналога нет. Требуется ручная реализация с использованием функций типа strstr() и манипуляций с буфером.

JS replaceAll function comments

En
ReplaceAll Returns a new string with all matches of a pattern replaced by a replacement