Avatar ·

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

Привет! Я новичок в JavaScript и столкнулся с проблемой при работе со строками. Мне нужно заменить все вхождения определённого слова в тексте, но почему-то заменяется только первое совпадение. Вот мой код: ```javascript let text = "Кошка гуляет по крыше. Кошка любит молоко. Кошка спит на диване."; let newText = text.replace("Кошка", "Собака"); console.log(newText); // Выводит: "Собака гуляет по крыше. Кошка любит молоко. Кошка спит на диване." ``` Как видите, заменилось только первое слово "Кошка", а остальные остались без изменений. Я пробовал искать в документации, но там написано что-то про регулярные выражения, в которых я пока не разбираюсь. Может быть, есть простой способ заменить все вхождения без использования сложных конструкций? Или без регулярных выражений тут не обойтись? Буду благодарен за понятный пример с объяснением, как это работает. Также интересует, как быть, если нужно заменять с учётом регистра (например, "кошка" и "Кошка" — это разные слова) или без учёта регистра. Заранее спасибо! <<>>

Проблема: почему replace() заменяет только первое совпадение?

Метод String.prototype.replace() по умолчанию заменяет только первое найденное совпадение. Это его стандартное поведение, если не использовать регулярное выражение с флагом g (global).

В вашем примере:

text.replace("Кошка", "Собака")

— строка "Кошка" интерпретируется как литерал, и замена происходит только для первого вхождения.

Решение 1: Использование replace() с регулярным выражением (рекомендуется)

Самый правильный и гибкий способ — использовать регулярное выражение с флагом g (global) для замены всех вхождений. Флаг i (ignore case) позволяет игнорировать регистр.

Пример 1: замена всех вхождений с учётом регистра

let text = "Кошка гуляет по крыше. Кошка любит молоко. Кошка спит на диване.";
let newText = text.replace(/Кошка/g, "Собака");
console.log(newText);
// "Собака гуляет по крыше. Собака любит молоко. Собака спит на диване."

Пример 2: замена всех вхождений без учёта регистра

let text = "Кошка гуляет. кошка спит. КОШКА ест.";
let newText = text.replace(/кошка/gi, "Собака");
console.log(newText);
// "Собака гуляет. Собака спит. Собака ест."

Флаги:

  • g — global, заменяет все совпадения, а не только первое.
  • i — ignore case, игнорирует регистр символов.

Решение 2: Использование replaceAll() (современный способ, ES2021+)

Начиная с ES2021, в JavaScript появился метод String.prototype.replaceAll(). Он заменяет все вхождения без необходимости использовать регулярные выражения.

Пример 3: replaceAll() с учётом регистра

let text = "Кошка гуляет по крыше. Кошка любит молоко. Кошка спит на диване.";
let newText = text.replaceAll("Кошка", "Собака");
console.log(newText);
// "Собака гуляет по крыше. Собака любит молоко. Собака спит на диване."

Важно: replaceAll() не поддерживает флаг i. Для замены без учёта регистра всё равно нужно использовать регулярное выражение с replace() или replaceAll() с предварительным приведением строки к одному регистру.

Решение 3: Замена без учёта регистра с помощью replaceAll() и toLowerCase()

let text = "Кошка гуляет. кошка спит. КОШКА ест.";
let search = "кошка";
let replacement = "Собака";

// Приводим исходный текст и искомое слово к нижнему регистру,
// но сохраняем оригинал для замены.
let lowerText = text.toLowerCase();
let lowerSearch = search.toLowerCase();
let result = "";

// Разделяем по искомому слову (в нижнем регистре) и склеиваем с заменой
let parts = lowerText.split(lowerSearch);
result = parts.join(replacement);

console.log(result); 
// "Собака гуляет. Собака спит. Собака ест."

Сравнение методов

  • replace() + регулярное выражение — самый гибкий вариант, работает во всех средах. Подходит для сложных шаблонов.
  • replaceAll() — проще читается, но не поддерживает флаги i и g (он и так глобальный). Подходит для простых замен без учёта регистра.
  • split() + join() — старый трюк, работает без регулярных выражений, но менее производителен на больших строках.

Рекомендую освоить регулярные выражения — они значительно расширяют ваши возможности при работе со строками в JavaScript.

<<>>

Альтернативный подход: использование split() и join()

Если вы пока не хотите разбираться с регулярными выражениями, есть простой «трюк»: разбить строку на массив по искомой подстроке, а затем склеить обратно с нужной заменой.

let text = "Кошка гуляет по крыше. Кошка любит молоко. Кошка спит на диване.";
let newText = text.split("Кошка").join("Собака");
console.log(newText);
// "Собака гуляет по крыше. Собака любит молоко. Собака спит на диване."

Как это работает:

  • split("Кошка") — разбивает строку на массив частей, удаляя все вхождения "Кошка".
  • .join("Собака") — склеивает все элементы массива обратно в строку, вставляя между ними "Собака".

Недостатки:

  • Нельзя просто добавить игнорирование регистра (придётся дополнительно преобразовывать строку).
  • Менее производительно на очень длинных строках (создаётся промежуточный массив).
  • Не подходит для сложных шаблонов (например, замена всех цифр на звёздочки).

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