Как работает метод replace() в JavaScript

Ответ

Метод String.prototype.replace() возвращает новую строку, в которой одно, несколько или все совпадения с шаблоном заменены на указанную замену. Исходная строка не изменяется.

Синтаксис:

const newString = originalString.replace(pattern, replacement);

Параметры:

  1. pattern — может быть строкой или регулярным выражением (RegExp).
  2. replacement — может быть строкой или функцией.

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

  • Если pattern — строка, заменяется только первое совпадение.
  • Для глобальной замены всех совпадений необходимо использовать регулярное выражение с флагом g.
  • В строке замены можно использовать специальные паттерны вроде $& (совпадение целиком), $` (текст до совпадения), $' (текст после совпадения).
  • Если replacement — функция, она выполняется для каждого совпадения, и ее возвращаемое значение используется как замена.

Примеры:

// 1. Базовая замена строки
const greeting = 'Hello, World!';
console.log(greeting.replace('World', 'Node.js')); // 'Hello, Node.js!'

// 2. Глобальная замена с RegExp
const spaces = 'a b c d';
console.log(spaces.replace(/s/g, '-')); // 'a-b-c-d'

// 3. Использование групп захвата в строке замены
const date = '2023-12-25';
console.log(date.replace(/(d{4})-(d{2})-(d{2})/, '$2/$3/$1')); // '12/25/2023'

// 4. Замена через функцию (полезно для сложной логики)
const celsius = 'Temperature is 25C';
const fahrenheit = celsius.replace(/(d+)C/, (match, p1) => {
    const tempC = parseInt(p1, 10);
    const tempF = (tempC * 9/5) + 32;
    return `${tempF}F`;
});
console.log(fahrenheit); // 'Temperature is 77F'

// 5. Практический пример в Node.js: санитизация ввода
function sanitizeInput(input) {
    return input
        .replace(/<scriptb[^<]*(?:(?!</script>)<[^<]*)*</script>/gi, '') // Удалить теги <script>
        .replace(/&/g, '&amp;') // Экранировать HTML-сущности
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}

const userInput = '<script>alert("xss")</script>Hello & World';
console.log(sanitizeInput(userInput)); // 'Hello &amp; World'

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

console.log('foo foo foo'.replaceAll('foo', 'bar')); // 'bar bar bar'

Ответ 18+ 🔞

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

Вот смотри, есть у тебя строка. И ты хочешь что-то в ней поменять. replace() — это твой инструмент. Но он, как хитрая жопа, работает по-разному, и это надо понимать.

Синтаксис простой, как три копейки:

const newString = originalString.replace(pattern, replacement);

Параметры:

  1. pattern — это то, что ищешь. Можешь скормить ему просто текст или регулярку (RegExp).
  2. replacement — на что менять. Тоже либо строка, либо функция.

А теперь ловушки, из-за которых все и пиздец:

  • Если ты передашь просто строку в pattern, то метод заменит только первое совпадение. Хочешь заменить всё? Тогда нужна регулярка с флагом g. Иначе будешь сидеть и думать: «Ну какого хуя он заменил только одно слово?»
  • В строке замены есть свои спецсимволы. Например, $& — это всё найденное совпадение. Полезная штука, но если не знаешь — выглядит как хуй в пальто.
  • Если передаёшь функцию — она вызовется для каждого совпадения, и что она вернёт, то и вставится на место старого текста. Мощная вещь, когда нужно не просто заменить, а ещё и пошаманить с данными.

Примеры, чтобы стало понятно:

// 1. Банальная замена. Всё просто.
const greeting = 'Hello, World!';
console.log(greeting.replace('World', 'Node.js')); // 'Hello, Node.js!'

// 2. А вот тут уже интереснее. Хочешь заменить ВСЕ пробелы? Без регулярки с флагом 'g' — нихуя не выйдет.
const spaces = 'a b c d';
console.log(spaces.replace(/s/g, '-')); // 'a-b-c-d'

// 3. Группы захвата в регулярках — это вообще магия. Меняешь местами дату, например.
const date = '2023-12-25';
console.log(date.replace(/(d{4})-(d{2})-(d{2})/, '$2/$3/$1')); // '12/25/2023'

// 4. Функция как замена. Вот тут можно мозги включить.
const celsius = 'Temperature is 25C';
const fahrenheit = celsius.replace(/(d+)C/, (match, p1) => {
    const tempC = parseInt(p1, 10);
    const tempF = (tempC * 9/5) + 32;
    return `${tempF}F`;
});
console.log(fahrenheit); // 'Temperature is 77F'

// 5. Практика из жизни: почистить пользовательский ввод от всякой хуйни.
function sanitizeInput(input) {
    return input
        .replace(/<scriptb[^<]*(?:(?!</script>)<[^<]*)*</script>/gi, '') // Вырезаем скрипты, ебать колотить
        .replace(/&/g, '&amp;') // Экранируем спецсимволы HTML
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}

const userInput = '<script>alert("xss")</script>Hello & World';
console.log(sanitizeInput(userInput)); // 'Hello &amp; World'

И последнее, блядь, важное: Если тебе нужно тупо заменить одну подстроку на другую везде, и терпения ноль ебать заморачиваться с регулярками, есть метод replaceAll() (появился в ES2021). Он прям для таких ленивых, как я.

console.log('foo foo foo'.replaceAll('foo', 'bar')); // 'bar bar bar'

Вот и вся история. Главное — помни про флаг g в регулярках, а то будешь, как полупидор, одну запятую в тексте менять.