Поиск совпадений в строке: JavaScript match()

Раздел: Программирование -> Строки

Метод match() в работе со строками

Метод match() предназначен для поиска подстрок по регулярному выражению. Он возвращает массив совпадений или null, если совпадений нет.

Основной вызов match() с регулярным выражением без флагов позволяет получить первое совпадение. В возвращаемый массив добавляются свойства index, input и groups.

const str = 'Цена 150 рублей, скидка 15%';
const result = str.match(/15/);
console.log(result[0]);
console.log(result.index);
console.log(result.input);

Js split (разделение строк в javascript)

15
7
Цена 150 рублей, скидка 15%

Js заменить (замена строк в javascript)

Последовательность действий:

  1. Объявляется строка с текстом.
  2. Вызывается match() с регулярным выражением /15/.
  3. В переменную result записывается массив с одним элементом, так как совпадение единственное и флаг g отсутствует.
  4. Обращение к result[0] возвращает найденную подстроку.
  5. Свойство index хранит позицию начала совпадения в исходной строке.
  6. Свойство input содержит исходную строку.
Если совпадение не найдено, метод вернёт null. При попытке прочитать result[0] возникнет ошибка. Способ предотвращения состоит в проверке результата на null перед обращением к элементам массива. Также без флага g невозможно получить все вхождения.

Как найти все вхождения подстроки?

Флаг g изменяет поведение метода: возвращается массив всех найденных совпадений.

const text = 'cat, cot, cut';
const matches = text.match(/c.t/g);
console.log(matches);

символы js (символы в javascript)

['cat', 'cot', 'cut']

Js замена (javascript: замена подстрок)

В шаблоне c.t точка соответствует любому символу. Флаг g заставляет регулярное выражение продолжать поиск после каждого найденного совпадения, поэтому в массив попадают все подходящие последовательности.

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

Распространённая ошибка: попытка прочитать свойство index у результата с флагом g. Возвращается undefined. При необходимости позиций нужно отказаться от g либо использовать matchAll().

Как выполнить поиск без учёта регистра?

Модификатор i отключает чувствительность к регистру символов.

const text = 'Привет, ПРИВЕТ, привет';
const result = text.match(/привет/gi);
console.log(result);

Match js (javascript: метод match())

['Привет', 'ПРИВЕТ', 'привет']

Здесь одновременно используются флаги g и i. Поиск охватывает все вхождения независимо от регистра. Такой подход удобен при обработке текстового ввода пользователя, где слова могут быть написаны в разном виде.

Без флага i совпадение было бы найдено только для точного написания строчными буквами. С флагом g все варианты будут включены в массив, но порядок элементов соответствует порядку появления в строке.

Как заставить якоря работать с каждой строкой текста?

Флаг m изменяет значение якорей ^ и $. Они начинают соответствовать началу и концу каждой строки, а не всей строки целиком.

const multiline = 'first line\nsecond line\nthird';
const result = multiline.match(/^\w+/gm);
console.log(result);
['first', 'second', 'third']

В примере ^\w+ находит слово в начале каждой строки. Без флага m совпадение было бы только одно: слово first в начале всей строки. Режим m полезен при разборе списков, логов или CSV-данных.

Без флага m совпадение искалось бы только в начале всей строки, что ограничивает поиск при работе с многострочным текстом.

Как извлечь части совпадения с понятными именами?

Именованные захватывающие группы оформляются как (?<name>...). После совпадения доступ к значениям групп открывается через свойство groups.

const date = 'Сегодня 21.05.2024';
const match = date.match(/(?<day>\d{2})\.(?<month>\d{2})\.(?<year>\d{4})/);
console.log(match.groups.day);
console.log(match.groups.month);
console.log(match.groups.year);
21
05
2024

Именованные группы упрощают чтение кода, потому что не нужно запоминать порядок групп.

Если используется флаг g, то возвращается только массив строк без групп. Для работы с группами и флагом g одновременно потребуется matchAll().

Как заставить точку соответствовать переводу строки?

По умолчанию точка не совпадает с \n. Флаг s включает режим dotAll: точка соответствует любому символу, включая перевод строки.

const text = 'line1\nline2';
const match = text.match(/line1.line2/s);
console.log(match[0]);
line1
line2

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

Флаг s поддерживается не во всех старых средах. Перед применением стоит проверить таблицу совместимости.

Как корректно работать с Unicode символами?

Флаг u включает полную поддержку Unicode в регулярных выражениях. Становятся доступными свойства \p{...} и корректная обработка суррогатных пар.

const emoji = 'Тест - ? и ?';
const result = emoji.match(/\p{Emoji}/gu);
console.log(result);
['?', '?']

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

Как получить все совпадения с позициями и группами?

Метод matchAll() возвращает итератор по всем совпадениям. Каждое совпадение содержит index и groups.

const str = '2024-05-21, 2024-06-01';
const regex = /(\d{4})-(\d{2})-(\d{2})/g;
for (const match of str.matchAll(regex)) {
  console.log(match.index, match[0], match[1], match[2], match[3]);
}
0 2024-05-21 2024 05 21
12 2024-06-01 2024 06 01

Метод matchAll() требует обязательный флаг g, иначе выбрасывается ошибка TypeError.

В старых браузерах matchAll() может отсутствовать. Совместимость обеспечивается с помощью цикла и метода exec().

Как искать специальные символы буквально?

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

const url = 'https://example.com';
const match = url.match(/\.com/);
console.log(match[0]);
.com

Экранирование превращает точку из метасимвола в обычный символ. Это необходимо при обработке доменных имён, IP-адресов и математических выражений.

Если точку не экранировать, она будет соответствовать любому символу. Это приводит к ложным срабатываниям.

Расширенные примеры использования match()

Дополнительные примеры показывают разнообразные сценарии применения метода match().

Пример
const data = 'Заказ №5: 150.50 руб, скидка 10% и бонус 3.25';
const numbers = data.match(/\d+(?:\.\d+)?/g);
console.log(numbers);
['5', '150.50', '10', '3.25']

Шаблон \d+ находит цифры, а необязательная группа (?:\.\d+)? добавляет десятичную часть.

Пример
const url = 'https://site.com:8080/path/page?x=1&y=2#section';
const regex = /^(https?):\/\/([^:\/\s]+):?(\d*)?([^#\?]*)\?([^#]*)#?(.*)$/;
const match = url.match(regex);
const [, protocol, host, port, path, query, hash] = match;
console.log(protocol, host, port, path, query, hash);
https site.com 8080 /path/page x=1&y=2 section

Обратите внимание на экранирование слешей и использование групп для разделения компонентов URL.

Пример
const text = 'Контакты: test@example.com, info@site.org';
const emails = text.match(/\b[\w.+-]+@[\w-]+(?:\.[\w-]+)+\b/g);
console.log(emails);
['test@example.com', 'info@site.org']

Регулярное выражение для поиска email охватывает типичные символы в локальной части и домене.

Пример
const phrase = 'это это повторение, тут тут слово';
const duplicates = phrase.match(/\b(\w+)\s+\1\b/g);
console.log(duplicates);
['это это', 'тут тут']

Обратная ссылка \1 соответствует той же строке, что и первая захваченная группа.

Пример
const text = 'Он сказал "Привет" и "Пока"';
const quoted = text.match(/"([^"]+)"/g);
console.log(quoted);
['"Привет"', '"Пока"']

В регулярном выражении двойные кавычки экранированы не для JS, а для наглядности шаблона. В коде достаточно написать /"([^"]+)"/g.

Пример
const query = '?a=1&b=2&c=3';
const regex = /([^&=]+)=([^&]*)/g;
const params = {};
for (const match of query.matchAll(regex)) {
  params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
console.log(params);
{a: '1', b: '2', c: '3'}

Метод matchAll() удобен для разбора параметров запроса.

Пример
const css = 'color: #ff0000; background: #00ff00; border: 1px solid #000';
const hex = css.match(/#[0-9a-fA-F]{6}\b/g);
console.log(hex);
['#ff0000', '#00ff00']

Граница слова \b предотвращает частичное совпадение для сокращённых кодов.

Пример
const numbers = '15 20 45 5 30';
const result = numbers.match(/\b\d{2}\b/g);
console.log(result);
['15', '20', '45', '30']

Шаблон \b\d{2}\b находит двузначные числа.

Пример
const text = 'start\n...\nend';
const match = text.match(/start.*end/s);
console.log(match[0].length);
13

Флаг s позволяет точке пересекать перевод строки.

Пример
const sentence = 'Съешь ещё этих мягких булок';
const words = sentence.match(/[А-Яа-яЁё]+/g);
console.log(words);
['Съешь', 'ещё', 'этих', 'мягких', 'булок']

Класс символов \p{L} можно использовать для поиска букв независимо от языка, но флаг u обязателен.

Пример
const str = 'Это пример: example';
const result = str.match('example');
console.log(result[0]);
example

Переданная строка автоматически преобразуется в регулярное выражение без флагов.

Пример
const data = 'Номер 12345';
const digitSubstring = data.match(/\d+/);
console.log(digitSubstring ? digitSubstring[0] : 'Цифр нет');
12345

Проверка на наличие цифр выполняется через сравнение результата с null.

JavaScript: метод match() - comments

En
Match js (javascript)