66. Regex Groups
Regex groups (группы регулярных выражений) позволяют извлекать конкретные части совпадающей строки. Это мощный инструмент для разбора и обработки текста. В этом уроке мы разберемся, как их использовать.
## Что такое Regex Groups?
Regex Groups — это способ выделить отдельные части шаблона регулярного выражения, чтобы потом их использовать. Они определяются с помощью круглых скобок `( )`. Когда регулярное выражение с группами применяется к строке, движок regex запоминает части строки, которые соответствуют каждой группе.
### Пример 1: Простое извлечение имени и фамилии
Допустим, у нас есть строка с именем и фамилией, разделенными пробелом, и мы хотим извлечь имя и фамилию отдельно.
```javascriptconst nameString = "Иван Иванов";const regex = /(\w+)\s(\w+)/; // Первая группа: имя, вторая группа: фамилияconst match = nameString.match(regex);
if (match) { const firstName = match[1]; // Индекс 0 - вся строка, 1 - первая группа const lastName = match[2]; // 2 - вторая группа
console.log("Имя:", firstName); // Вывод: Имя: Иван console.log("Фамилия:", lastName); // Вывод: Фамилия: Иванов}В этом примере (\w+) соответствует одному или нескольким буквенным символам (имя или фамилия), а \s соответствует пробелу. match[1] содержит текст, соответствующий первой группе (имя), а match[2] — текст, соответствующий второй группе (фамилия).
Пример 2: Извлечение даты
Заголовок раздела «Пример 2: Извлечение даты»Предположим, у нас есть дата в формате YYYY-MM-DD, и мы хотим извлечь год, месяц и день.
const dateString = "2023-10-26";const regex = /(\d{4})-(\d{2})-(\d{2})/; // Группы: год, месяц, деньconst match = dateString.match(regex);
if (match) { const year = match[1]; const month = match[2]; const day = match[3];
console.log("Год:", year); // Вывод: Год: 2023 console.log("Месяц:", month); // Вывод: Месяц: 10 console.log("День:", day); // Вывод: День: 26}Здесь \d{4} соответствует четырем цифрам (год), \d{2} соответствует двум цифрам (месяц и день).
Пример 3: Использование Named Capture Groups (именованные группы захвата)
Заголовок раздела «Пример 3: Использование Named Capture Groups (именованные группы захвата)»Начиная с ES2018, можно давать группам имена, что делает код более читаемым.
const dateString = "2023-10-26";const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;const match = dateString.match(regex);
if (match) { const year = match.groups.year; const month = match.groups.month; const day = match.groups.day;
console.log("Год:", year); // Вывод: Год: 2023 console.log("Месяц:", month); // Вывод: Месяц: 10 console.log("День:", day); // Вывод: День: 26}В этом примере (?<year>\d{4}) дает группе имя “year”. Доступ к захваченным значениям осуществляется через match.groups.year.
Жизненный пример
Заголовок раздела «Жизненный пример»Regex Groups часто используются в парсинге URL-адресов. Например, можно извлечь протокол, домен и путь из URL.
const url = "https://www.example.com/path/to/page";const regex = /(?<protocol>\w+):\/\/(?<domain>[\w.]+)\/(?<path>.*)/;const match = url.match(regex);
if (match) { const protocol = match.groups.protocol; const domain = match.groups.domain; const path = match.groups.path;
console.log("Протокол:", protocol); // Вывод: Протокол: https console.log("Домен:", domain); // Вывод: Домен: www.example.com console.log("Путь:", path); // Вывод: Путь: path/to/page}Фреймворки, такие как React и Angular, используют регулярные выражения для маршрутизации, где группы используются для извлечения параметров из URL-адреса. Например, адрес /users/123 можно разобрать, чтобы получить ID пользователя (123).
Ключевые моменты
Заголовок раздела «Ключевые моменты»- Группы определяются круглыми скобками
( ). - Доступ к группам осуществляется через индексы в массиве
match, начиная с 1 (0 - вся строка). - Именованные группы захвата (Named Capture Groups) (
(?<name>...)) делают код более читаемым. - Regex Groups полезны для извлечения и обработки частей текста.
- Используются в парсинге URL, маршрутизации и других задачах обработки текста.
## Интерактивный пример
<Playground client:load template="static" files={{ "/index.html": `<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <style> body { background: #1e1e2e; color: #cdd6f4; font-family: sans-serif; padding: 16px; margin: 0; } button { background: #89b4fa; color: #1e1e2e; border: none; padding: 7px 14px; border-radius: 6px; cursor: pointer; margin: 3px; font-size: 13px; font-weight: 600; } button:hover { background: #74c7ec; } .box { background: #313244; border-radius: 8px; padding: 14px; margin: 8px 0; } .out { background: #181825; border-radius: 6px; padding: 10px; font-family: monospace; font-size: 12px; min-height: 100px; color: #a6e3a1; white-space: pre-wrap; } h3 { color: #cba6f7; margin: 0 0 10px; font-size: 14px; } input { background: #313244; color: #cdd6f4; border: 1px solid #45475a; padding: 5px 8px; border-radius: 4px; font-size: 13px; width: 260px; margin-bottom: 6px; display: block; } label { font-size: 12px; color: #a6adc8; display: block; margin-bottom: 2px; } </style></head><body> <div class="box"> <h3>Тестер групп в регулярных выражениях</h3> <label>Строка для теста:</label> <input id="text" value="2024-03-15"> <label>Паттерн (без //):</label> <input id="pattern" value="(\d{4})-(\d{2})-(\d{2})"> <label>Именованный паттерн:</label> <input id="named" value="(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})"> <button onclick="testGroups()">Тест групп</button> <button onclick="testNamed()">Тест именованных групп</button> </div> <div class="out" id="out">Введите строку и паттерн, нажмите кнопку...</div> <script> var out = document.getElementById('out'); window.testGroups = function() { var text = document.getElementById('text').value; var pat = document.getElementById('pattern').value; try { var re = new RegExp(pat); var m = text.match(re); if (!m) { out.textContent = 'Нет совпадений для: /' + pat + '/'; return; } var lines = ['Строка: "' + text + '"', 'Паттерн: /' + pat + '/', '', 'Результат:']; lines.push(' match[0] (вся строка): "' + m[0] + '"'); for (var i = 1; i < m.length; i++) lines.push(' match[' + i + '] (группа ' + i + '): "' + m[i] + '"'); out.textContent = lines.join('\\n'); } catch(e) { out.textContent = 'Ошибка в паттерне: ' + e.message; } } window.testNamed = function() { var text = document.getElementById('text').value; var pat = document.getElementById('named').value; try { var re = new RegExp(pat); var m = text.match(re); if (!m) { out.textContent = 'Нет совпадений'; return; } var lines = ['Строка: "' + text + '"', 'Паттерн: /' + pat + '/', '', 'Именованные группы (match.groups):']; if (m.groups) { Object.keys(m.groups).forEach(function(k) { lines.push(' ' + k + ': "' + m.groups[k] + '"'); }); } else { lines.push(' (нет именованных групп)'); } out.textContent = lines.join('\\n'); } catch(e) { out.textContent = 'Ошибка: ' + e.message; } } </script></body></html>`, }}/>