Образец Java Regex, сопоставляющий первое вхождение "границы" после любой последовательности символов
Я хочу установить шаблон, который найдет группу захвата, ограниченную первым вхождением "границы". Но теперь используется последняя граница.
например:.
String text = "this should match from A to the first B and not 2nd B, got that?";
Pattern ptrn = Pattern.compile("\\b(A.*B)\\b");
Matcher mtchr = ptrn.matcher(text);
while(mtchr.find()) {
String match = mtchr.group();
System.out.println("Match = <" + match + ">");
}
печатает:
"Match = <A to the first B and not 2nd B>"
и я хочу, чтобы он печатался:
"Match = <A to the first B>"
Что мне нужно изменить внутри шаблона?
Ответы
Ответ 1
Сделайте свой *
неживым/неохотным, используя *?
:
Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");
По умолчанию шаблон будет вести себя жадно и будет соответствовать как можно большему количеству символов, чтобы удовлетворить шаблон, то есть до последнего B.
См. "Недостаточные квантификаторы" документы и этот учебник.
Ответ 2
Не используйте жадные выражения для сопоставления, т.е.:
Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");
Ответ 3
*
- это жадный квантификатор, который соответствует как можно большему количеству символов, чтобы удовлетворить шаблон. До последнего события B
в вашем примере. Вот почему вам нужно использовать неохотный: *?
, который будет обрабатывать как можно больше символов. Итак, ваш шаблон должен быть слегка изменен:
Pattern ptrn = Pattern.compile("\\b(A.*?B)\\b");
Смотрите "неохотные квантификаторы" в документы и этот учебник.
Ответ 4
Возможно, более явным, чем отказ *
неохотно/ленивый, будет сказать, что вы ищете A, за которым следует куча вещей, которые не являются B, а затем B:
Pattern ptrn = Pattern.compile("\\b(A[^B]*B)\\b");