Ты почти у цели.Шаблон, который вы ищете: \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
Обратите внимание, что это не лучшее решение, поскольку оно будет продолжать поиск трейлера для каждого найденного совпадения.