Próbuję dopasować adres URL w ciągu, używając wyrażenia regularnego stąd: Wyrażenie regularne pasujące do adresów URL w Javie
Działa dobrze z jednym adresem URL, ale gdy mam dwa adresy URL w ciągu, pasuje tylko do tego ostatniego.
Oto kod:
Pattern pat = Pattern.compile(".*((https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|])", Pattern.DOTALL);
Matcher matcher = pat.matcher("asdasd http://www.asd.as/asd/123 or http://qwe.qw/qwe");
// now matcher.groupCount() == 2, not 4
Edycja: rzeczy, które próbowałem:
// .* removed, now doesn"t match anything // Another edit: actually works, see below
Pattern pat = Pattern.compile("((https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|])", Pattern.DOTALL);
// .* made lazy, still only matches one
Pattern pat = Pattern.compile(".*?((https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|])", Pattern.DOTALL);
Jakieś pomysły?
Odpowiedzi:
4 dla odpowiedzi № 1To dlatego, że .*
jest chciwy. Zużyje tyle, ile to możliwe (cały ciąg), a następnie cofa się. To znaczy. odrzuci jeden znak na raz, aż pozostałe znaki będą mogły utworzyć adres URL. Dlatego pierwszy adres URL zostanie już dopasowany, ale nie zostanie przechwycony. I niestety mecze nie mogą się pokrywać. Poprawka powinna być prosta. Usunąć .*
na początku twojego wzoru. Następnie możesz również usunąć zewnętrzne nawiasy ze wzorca - nie musisz już niczego przechwytywać, ponieważ całe dopasowanie będzie adresem URL, którego szukasz.
Pattern pat = Pattern.compile("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]", Pattern.DOTALL);
Matcher matcher = pat.matcher("asdasd http://www.asd.as/asd/123 or http://qwe.qw/qwe");
while (matcher.find()) {
System.out.println(matcher.group());
}
Tak poza tym, matcher.groupCount()
nic ci nie mówi, ponieważ podaje liczbę grup we wzorcu, a nie liczbę przechwyceń w ciągu docelowym. Dlatego twoje drugie podejście (przy użyciu .*?
) nie pomogło. Nadal masz dwie grupy przechwytujące w tupot. Przed dzwonieniem find
czy cokolwiek, matcher
nie wie, ile zdjęć w sumie znajdzie.