Понимаем и используем группы захвата в Java regex

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

При создании групп захвата в регулярных выражениях Java используйте круглые скобки "(\d+)-(\w+)", чтобы определить две группы: для чисел (\d+) и букв (\w+). Обработка данных групп происходит через классы Pattern и Matcher:

Java
Скопировать код
Pattern pattern = Pattern.compile("(\\d+)-(\\w+)");
Matcher matcher = pattern.matcher("123-abc");
if (matcher.find()) {
    String digits = matcher.group(1); // 123 — ...захвачено!
    String letters = matcher.group(2); // "abc" — ...успешно захвачено!
}

Отметим, что matcher.group(1) и matcher.group(2) возвращают содержимое соответствующих групп.

Кинга Идем в IT: пошаговый план для смены профессии

Разбираемся с квантификаторами и способами захвата

Квантификаторы: жадные, ленивые и ревнивые типы

Квантификаторы определяют, сколько символов, соответствующих шаблону, надо захватить:

  • Жадные (*): пытаются захватывать максимальное количество символов.
  • Ленивые (*?): стремятся захватить минимальное количество символов.
  • Ревнивые (*+): работают аналогично жадным, но не допускают возврата.

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

Принцип "слева направо"

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

Обратные ссылки и именованные группы

Обратные ссылки (\1, \2 и т.д.) позволяют сослаться на уже захваченные группы. В версиях Java 7 и выше доступна возможность использования именованных групп посредством (?<name>...), что улучшает читабельность кода.

Обеспечение точного соответствия

Незахватывающие группы

Незахватывающие группы (?:...) позволяют применить квантификаторы, не захватывая содержимое.

Три основных строительных блока

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

Крайние случаи

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

Визуализация

Для наглядного представления работы регулярных выражений удобно использовать аналогию с "отрядом захватчиков":

Markdown
Скопировать код
Отряд: [Командир, Группа 1 (Рейдер), Группа 2 (Собиратель), ..., Запасной]

Каждый член отряда отвечает за захват определённых шаблонов:

Java
Скопировать код
Pattern.compile("(Рейдер)(:)(\\d+)");

Отчет о захвате:

Markdown
Скопировать код
🦸‍♀️🎁📦: [Рейдер, ":", "12345"]

Дополнительные сценарии

Захват определённых данных

Чтобы извлечь расширения файлов, используем шаблон (\w+)\.(\w+):

Java
Скопировать код
Pattern p = Pattern.compile("(\\w+)\\.(\\w+)");
Matcher m = p.matcher("masterpiece.png");
if (m.find()) {
    String baseName = m.group(1);
    String ext = m.group(2);
}

Работа с опциональными элементами

Опциональные шаблоны описываются посредством (pattern)?:

Java
Скопировать код
Pattern p = Pattern.compile("ОЙ, (\\w+)(, приятель)?");
Matcher m = p.matcher("ОЙ, Брюс, приятель");
if (m.find()) {
    String name = m.group(1);
    String optional = m.group(2);
}

Группировка сложных форматов

Для работы с датами и другими сложными форматами выражений можно применять следующую конструкцию:

Java
Скопировать код
Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher m = p.matcher("2099-12-31");
if (m.find()) {
    String year = m.group(1);
    String month = m.group(2);
    String day = m.group(3);
}

Полезные материалы

Ссылки на дополнительные ресурсы по регулярным выражениям в Java и работе с классами Pattern и Matcher.