Вы, кажется, ожидаете, что (at \w+)+
совпадет с at Boston
и at Downtown
в первой строке. Это не работает, потому что вы не учитываете пространство до второй at
. Вам нужно изменить его на ( at \w+)+
или, что еще лучше, изменить его на группу без захвата и использовать группу захвата для части, которая вас действительно интересует:
Pattern p = Pattern.compile(".*?(?: at (\\w+))+.*");
String s1 = "I am at Boston at Downtown";
Matcher m = p.matcher(s1);
if (m.matches()) {
System.out.println(m.group(1));
}
Но теперь он печатает только Downtown
. Это потому, что вы пытаетесь использовать одну группу захвата для захвата двух подстрок. При первом совпадении (?: at (\\w+))+
он захватывает Boston
; во второй раз он сбрасывает Boston
и вместо этого захватывает Downtown
.
Существуют некоторые разновидности регулярных выражений, которые позволят вам получить промежуточные захваты (Boston
в этом примере), но Java не является одним из них. Ваш лучший вариант, вероятно, будет использовать find()
вместо matches()
, как предложено @arclight. Это также упрощает регулярные выражения:
Pattern p = Pattern.compile("\\bat\\s+(\\w+)");
String s1 = "I am at Boston at Downtown";
Matcher m = p.matcher(s1);
while (m.find()) {
System.out.println(m.group(1));
}
Вам больше не нужно совпадать с пробелом до at
, но вы, вероятно, хотите использовать \b
(границу слова), чтобы избежать совпадения с частичными словами (например, My c в в Бостоне в Центре ). И обычно хорошей идеей является использование \s+
вместо буквального пробела, если есть несколько пробелов, или пробел на самом деле является символом табуляции или чем-то еще.