RegExp capturing groups В этом посте расскажу про группы в ре | Java: fill the gaps
RegExp capturing groups
В этом посте расскажу про группы в регулярках и покажу, как извлечь данные из текста без лишней суеты.
Базовый синтаксис регулярных выражений можно почитать, например, в этой статье с кучей картинок. Группы — это уже уровень intermediate:)
Допустим, есть строка src:
Stack: Java 17, Spring Boot 2.7.1
Наша задача — вытащить отсюда версию джавы.
Этап 1. Начнём с простого варианта:
String p = "Java\\s\\d+";
Matcher m = Pattern.compile(p).matcher(src);
if (m.find()) {
res = m.group(); // Java 17
}
String version = res.substring(5); // 17
Этап 2: подключаем группы. В паттерн добавляются скобки
String p = "Java\\s(\\d+)";
После m.find() получаем следующее:
m.group() или m.group(0) → Java 17. В нулевой группе всегда содержится целиком найденное выражение
m.group(1) → 17
Получаем сразу версию, и substring нам больше не нужен
Пример посложнее. Из строки
Stack: Java 17, Spring Boot 2.7
нужно извлечь версию java и spring boot. Сделаем паттерн по аналогии:
String p = "Java\\s(\\d+).+Boot\\s(\\d+\\.\\d+)";
Здесь два выражения в скобках и, соответственно, две группы (помимо нулевой):
if (m.find()) {
javaVersion = m.group(1)); // 17
bootVersion = m.group(2); // 2.7
}
Чтобы сделать код более читаемым, дадим группам имена. Вот так:
(?X)
Где name — имя, X — регулярка.
Теперь обновляем паттерн
String p = "Java\\s(?\\d+).+Spring\\sBoot\\s(?\\d+\\.\\d+)";
Извлекаем версии
javaVersion = m.group("java");
bootVersion = m.group("boot");
Готово! Без групп пришлось бы использовать два паттерна и всякие методы с индексами, а с группами получился лаконичный и понятный код