Группировка в регулярных выражениях java

327
10 сентября 2017, 00:14

Подскажите. Есть код с сайта. Почему m.group(1) выдает Найдено значение: Крещение Руси произошло в 98 Почему m.group(2) выдает Найдено значение: 8

 import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class k4 {
   public static void main( String args[] ) {
  // Строка для сканирования, чтобы найти шаблон
  String str = "Крещение Руси произошло в 988 году! Не так ли?";
  String pattern = "(.*)(\\d+)(.*)";
  // Создание Pattern объекта
  Pattern r = Pattern.compile(pattern);
  // Создание matcher объекта

  Matcher m = r.matcher(str);
  if (m.find( )) {
     System.out.println("Найдено значение: " + m.group(0));
     System.out.println("Найдено значение: " + m.group(1));
     System.out.println("Найдено значение: " + m.group(2));
  }else {
     System.out.println("НЕ СОВПАДАЕТ");
  }

} }

Answer 1

Давайте разберём данное регулярное выражение : В интерпретаторе regex джавы пишут \\ вместо \ (как в большинстве языков), я разбиру как в большинстве.

(.*)(\d+)(.*)

. - любой символ | .* - строка из любых символов кроме \n, количество от 0 до бесконечности (жадный отбор строки).

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

\d - цифра, \d+ - строка из любых цифр, количество от 1 до бесконечности

(\d+) - группа состоящая только из цифр.

А теперь разберём, что мы имеем для (.*)(\d+)(.*):

Крещение Руси произошло в 988 году! Не так ли?

Сначало выражение жадно читает абсолютно все символы, коих может быть от 0 до беск. После этой части у нас должны быть цифры, коих есть от 1 до беск. и опять символы тупо до конца строки, которые сформируют 3 группу. Учитывая, что первая группа жадная, то она решает, что после неё как минимум должна идти одна цифра, она как истинная жадина забирает всё, что плохо лежит, т.е. 98 и оставляет 1 восьмёрку для 2 группы.

Противоположность жадности - лень (лень забирать, что-нибудь). 1 группа знает, что 2 группа начинается с цифр и встретив их она ленится идти дальше и передаёт бразды правления 2 группе.

Т.е. правильная запись регулярки (.*?)(\d+)(.*).

? - указатель, что набирание элементов ленивое.

READ ALSO
Заполнить матрицу треугольником

Заполнить матрицу треугольником

решение должно построить пирамиду из заданного входного списка целых значенийНомера сортируются по возрастанию сверху вниз, слева направо

432
Как настроить KeyEvent Android

Как настроить KeyEvent Android

Хочу в приложении сделать поддержку некоторых спец клавиш (F1, F2, F3

220
Как к view прикрепить скрытую информацию

Как к view прикрепить скрытую информацию

Допусти есть listView состоящий из textView'sНужно к каждому textView прицепить какие-то данные, но чтобы они не были видны пользователю

215
Как работать с выражениями {val} в @GetMapping(“/{val}”) в spring?

Как работать с выражениями {val} в @GetMapping(“/{val}”) в spring?

При работе с Spring столкнулся с таким синтаксисом {val} в мапингеВот такой метод:

215