Получи случайную криптовалюту за регистрацию!

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");

Готово! Без групп пришлось бы использовать два паттерна и всякие методы с индексами, а с группами получился лаконичный и понятный код