/ / Dopasowywanie kilku adresów URL w ciągu za pomocą regex - java, regex

Dopasowywanie kilku adresów URL w ciągu znaków za pomocą regex - java, regex

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 № 1

To 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.