Сопоставьте ранее захваченную группу с регулярным выражением (обратная ссылка?)

Я пытаюсь захватить серию чисел из определенной строки в абзаце текста, используя регулярное выражение. В приведенном ниже упрощенном примере я просто пытаюсь зафиксировать 4-значные номера в разделе «Активные телефонные линии». Я предполагаю, что существует неизвестное количество активных телефонных линий, и номера не могут повторяться:

User Names: bob, jill, toni, tom
Active Phone Lines: 1010, 2020, 3030, 4040, 5050, 6060, 7070
Inactive Phone Lines: 1111, 2222, 3333, 4444, 5555

Я знаю, что могу разделить строку по символам возврата каретки/перевода строки и просто использовать регулярное выражение ([0-9]{4}), но мне стало любопытно, и я хочу посмотреть, могу ли я просто использовать одно регулярное выражение.

До сих пор мне удавалось получить все, что я хочу, с помощью следующего регулярного выражения:

(?<=Active Phone Lines: |, )([0-9]{4})(?=, |\rInactive Phone Lines:)

Но это захватит 2222, 3333 и 4444 «неактивных телефонных линий». Я знаю, что могу использовать обратные ссылки для ссылки на ранее захваченные группы, но, насколько я могу судить, я могу ссылаться на них только в порядке захвата, а не только в предыдущем захвате. И похоже, что это работает только в пределах одного и того же выражения, а не через несколько итераций поиска.

Есть ли способ вернуться к предыдущей захваченной группе? Предполагая, что $foo сделает это, я мог бы использовать следующее регулярное выражение:

(?<=Active Phone Lines: |$foo, )([0-9]{4})(?=$foo, |\rInactive Phone Lines:)

person dfreer    schedule 28.10.2013    source источник
comment
Эм, это java или php? Я тоже не совсем понимаю, что вы хотите. В PHP вы можете использовать что-то вроде этого (test)(this)(?2)(?1). Это будет соответствовать testthisthistest   -  person HamZa    schedule 28.10.2013
comment
Это будет использоваться в java. Цель состоит в том, чтобы захватить каждый 4-значный номер, который появляется после строки «Активные телефонные линии:», но перед строкой «Неактивные телефонные линии:». Проблема заключается в том, что существует неизвестное количество четырехзначных номеров, которые могут появиться после активных телефонных линий: .   -  person dfreer    schedule 04.01.2014


Ответы (1)


Вы можете использовать якорь \G следующим образом:

(?:Active Phone Lines:|\\G)[\\s,]*([0-9]{4})

In:

Pattern pattern = Pattern.compile("(?:Active Phone Lines:|\\G)[\\s,]*([0-9]{4})");
String test = "User Names: bob, jill, toni, tom"+
              "Active Phone Lines: 1010, 2020, 3030, 4040, 5050, 6060, 7070"+
              "Inactive Phone Lines: 1111, 2222, 3333, 4444, 5555";
Matcher matcher = pattern.matcher(test);
while (matcher.find()) {
    System.out.println(matcher.group(1));
}

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

демонстрация ideone

person Jerry    schedule 28.10.2013