Группы регулярных выражений Java с .* против обычных регулярных выражений

Я пытаюсь использовать регулярное выражение, чтобы захватить 2 части одной полной строки. У меня нормально работает регулярное выражение на http://gskinner.com/RegExr/.

Вот пример строки:

Regex is fun when it works 99

Вот мое регулярное выражение

(.*)\\s+(\\d+)$

Это группы, которые я получаю при использовании сопоставления Java (matches()) и шаблона:

1: Regex is fun when it works 99
2: Regex is fun when it works

Используя обычное регулярное выражение (на RegExr), я получаю результаты, которых действительно ожидаю:

1: Regex is fun when it works
2: 99

Есть ли какие-либо предостережения при добавлении Regex в Java, о которых мне нужно знать? У меня уже есть \\ для специальных символов. Может быть, есть хитрость в использовании . ?

Если вы хотите, чтобы пример приложения копировался и вставлялся:

String str = "Regex is fun when it works 33";
String regx = "(.*)\\s+(\\d+)$"

Pattern p = Pattern.compile(regx);
Matcher m = p.matcher(str);

if (m.matches()) {
   for (int i = 0; i < m.groupCount(); i++) {
      System.out.println(i + ": " + m.group(i));
   }
}

person Jdcc    schedule 14.04.2013    source источник


Ответы (2)


Причина, по которой вы не получаете ожидаемого 99, заключается в том, что все совпадение group(0) не учитывается в groupcount(), поэтому цикл for выходит из строя слишком рано.

Поэтому, если вы измените i < m.groupCount() на i <= m.groupCount(), вы получите

0: регулярное выражение — это весело, когда оно работает 99
1: регулярное выражение — это весело, когда оно работает
2: 99

person MikeM    schedule 14.04.2013
comment
Привет Майк, Ах, он прятался там все это время. Я чувствую себя идиотом! Должно быть, ржавеет. Спасибо, что указали на исправление :) - person Jdcc; 15.04.2013

Измените свой первый захват, чтобы он не был жадным, следующим образом:

(.*?)\\s+(\\d+)$

Обратитесь к разделу "Остерегайтесь жадности" в этом руководстве по регулярному выражению, но, проще говоря, ? делает предыдущий квантификатор * ленивым. То есть он перестанет потреблять персонажей как можно раньше.

person Sepster    schedule 14.04.2013
comment
Привет, Sepster, спасибо за быстрый ответ и более эффективное регулярное выражение! Это ленивое регулярное выражение лучше соответствует тому, что я хочу захватить. Также кажется, что у него будет лучшая производительность, но это всего лишь предположение :) Объединив это с ответом MikeM, я решил проблему! Спасибо! - person Jdcc; 15.04.2013