Как я могу сопоставить несколько вхождений с моим регулярным выражением? - PullRequest
0 голосов
/ 04 июня 2018

У меня есть следующее регулярное выражение:

(?s)Table.*?Seat (\\d).*?\\((\\d+).*?HOLE

и следующая структура файла:

Table xxx123
Seat 1: xxx (1537 xxx)
Seat 3: yyy (609 yyy)
Seat 5: zzz (485 zzz)
xxx123 HOLE

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

Я думал, что следующая модификация должна работать, но это не так:

(?s)Table.*?(Seat (\\d).*?\\((\\d+).*?).*?HOLE

1 Ответ

0 голосов
/ 04 июня 2018

Ты почти у цели.Шаблон, который вы ищете: \G:

Конец предыдущего матча

Затем он используется с find() петля.При первом вызове find(), \G соответствует началу ввода.При последующих вызовах он совпадает с концом предыдущего совпадения.

Чтобы не допустить совпадения с началом ввода, вы используете отрицательный упор нулевой ширины , а затем объединяете это сa | ИЛИ оператор , соответствующий тексту Table в начале ввода, и окружите его группой без захвата .

(?:           start non-capturing group
   (?!<^)         not at beginning of input
   \G             match end of previous match
  |             OR
   Table          match "Table"
)             end non-capturing group

Затем вы ищите и сопоставляете то, что хотите захватить.

.*?Seat (\d).*?\((\d+)

Теперь вы не хотите фактически соответствовать трейлеру (.*?HOLE), потому что это помешало бы \G продолжитьследующая find() итерация.Вместо этого вы просто гарантируете, что он там, используя положительный прогноз нулевой ширины .

(?=.*?HOLE)

Демо

String input = "Table xxx123\n" +
               "Seat 1: xxx (1537 xxx)\n" +
               "Seat 3: yyy (609 yyy)\n" +
               "Seat 5: zzz (485 zzz)\n" +
               "xxx123 HOLE";

String regex = "(?s)(?:(?<!^)\\G|Table).*?Seat (\\d).*?\\((\\d+)(?=.*?HOLE)";

Matcher m = Pattern.compile(regex).matcher(input);
while (m.find())
    System.out.println(m.group(1) + " " + m.group(2));

Вывод

1 1537
3 609
5 485

Обратите внимание, что это не лучшее решение, поскольку оно будет продолжать поиск трейлера для каждого найденного совпадения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...