Метод replace

У строк есть метод replace, который может заменять часть строки другой строкой.

console.log("папа".replace("п", "м"));

// ? мапа

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

console.log("Borobudur".replace(/[ou]/, "a"));

// ? Barobudur

console.log("Borobudur".replace(/[ou]/g, "a"));

// ? Barabadar

Имело бы смысл передавать опцию «заменить все» через отдельный аргумент, или через отдельный метод типа replaceAll. Но к сожалению, опция передаётся через саму регулярку.

Вся сила регулярок раскрывается, когда мы используем ссылки на найденные в строке группы, заданные в регулярке. Например, у нас есть строка, содержащая имена людей, одно имя на строчку, в формате «Фамилия, Имя». Если нам надо поменять их местами и убрать запятую, чтобы получилось «Имя Фамилия», мы пишем следующее:

console.log(

  "Hopper, Grace McCarthy, John Ritchie, Dennis"

    .replace(/([w ]+), ([w ]+)/g, "$2 $1"));

// ? Grace Hopper

//   John McCarthy

//   Dennis Ritchie

$1 и $2 в строчке на замену ссылаются на группы символов, заключённые в скобки. $1 заменяется текстом, который совпал с первой группой, $2 – со второй группой, и так далее, до $9. Всё совпадение целиком содержится в переменной $&.

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

Простой пример:

var s = "the cia and fbi";

console.log(s.replace(/(fbi|cia)/g, function(str) {

  return str.toUpperCase();

}));

// ? the CIA and FBI

А вот более интересный:

var stock = "1 lemon, 2 cabbages, and 101 eggs";

function minusOne(match, amount, unit) {

  amount = Number(amount) - 1;

  if (amount == 1) // остался только один, удаляем 's' в конце

    unit = unit.slice(0, unit.length - 1);

  else if (amount == 0)

    amount = "no";

  return amount + " " + unit;

}

console.log(stock.replace(/(d+) (w+)/g, minusOne));

// ? no lemon, 1 cabbage, and 100 eggs

Код принимает строку, находит все вхождения чисел, за которыми идёт слово, и возвращает строчку, где каждое число уменьшено на единицу.

Группа (d+) попадает в аргумент amount, а (w+) – в unit. Функция преобразовывает amount в число – и это всегда срабатывает, потому что наш шаблон как раз d+. И затем вносит изменения в слово, на случай, если остался всего один предмет или ни одного.

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК