Powiedzmy, że mam ciąg, który zawiera to:
HelloxxxHelloxxxHello
Kompiluję wzorzec w celu wyszukania hasła „Hello”
Pattern pattern = Pattern.compile("Hello");
Matcher matcher = pattern.matcher("HelloxxxHelloxxxHello");
Powinien znaleźć trzy dopasowania. Jak mogę policzyć, ile było meczów?
Próbowałem różnych pętli i używania, matcher.groupCount()
ale to nie zadziałało.
Odpowiedzi:
matcher.find()
nie znajduje wszystkich dopasowań, tylko następne dopasowanie.Rozwiązanie dla Java 9+
long matches = matcher.results().count();
Rozwiązanie dla Java 8 i starszych
Będziesz musiał wykonać następujące czynności. ( Począwszy od Java 9, istnieje ładniejsze rozwiązanie )
int count = 0; while (matcher.find()) count++;
Przy okazji,
matcher.groupCount()
to coś zupełnie innego.Kompletny przykład :
import java.util.regex.*; class Test { public static void main(String[] args) { String hello = "HelloxxxHelloxxxHello"; Pattern pattern = Pattern.compile("Hello"); Matcher matcher = pattern.matcher(hello); int count = 0; while (matcher.find()) count++; System.out.println(count); // prints 3 } }
Obsługa pokrywających się dopasowań
Liczenie dopasowań
aa
waaaa
powyższym fragmencie daje 2 .Aby uzyskać 3 dopasowania, czyli takie zachowanie:
Musisz szukać dopasowania w indeksie
<start of last match> + 1
w następujący sposób:String hello = "aaaa"; Pattern pattern = Pattern.compile("aa"); Matcher matcher = pattern.matcher(hello); int count = 0; int i = 0; while (matcher.find(i)) { count++; i = matcher.start() + 1; } System.out.println(count); // prints 3
źródło
while(matcher.find()){ matcher.region(matcher.end()-1, str.length()); count++; }
To powinno działać w przypadku dopasowań, które mogą się nakładać:
public static void main(String[] args) { String input = "aaaaaaaa"; String regex = "aa"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); int from = 0; int count = 0; while(matcher.find(from)) { count++; from = matcher.start() + 1; } System.out.println(count); }
źródło
W Javie 9 możesz użyć strumienia dostarczonego przez
Matcher.results()
long matches = matcher.results().count();
źródło
Jeśli chcesz używać strumieni Java 8 i jesteś uczulony na
while
pętle, możesz spróbować tego:public static int countPattern(String references, Pattern referencePattern) { Matcher matcher = referencePattern.matcher(references); return Stream.iterate(0, i -> i + 1) .filter(i -> !matcher.find()) .findFirst() .get(); }
Zastrzeżenie: działa to tylko w przypadku rozłącznych meczów.
Przykład:
public static void main(String[] args) throws ParseException { Pattern referencePattern = Pattern.compile("PASSENGER:\\d+"); System.out.println(countPattern("[ \"PASSENGER:1\", \"PASSENGER:2\", \"AIR:1\", \"AIR:2\", \"FOP:2\" ]", referencePattern)); System.out.println(countPattern("[ \"AIR:1\", \"AIR:2\", \"FOP:2\" ]", referencePattern)); System.out.println(countPattern("[ \"AIR:1\", \"AIR:2\", \"FOP:2\", \"PASSENGER:1\" ]", referencePattern)); System.out.println(countPattern("[ ]", referencePattern)); }
To drukuje:
2 0 1 0
To jest rozwiązanie dla rozłącznych meczów ze strumieniami:
public static int countPattern(String references, Pattern referencePattern) { return StreamSupport.stream(Spliterators.spliteratorUnknownSize( new Iterator<Integer>() { Matcher matcher = referencePattern.matcher(references); int from = 0; @Override public boolean hasNext() { return matcher.find(from); } @Override public Integer next() { from = matcher.start() + 1; return 1; } }, Spliterator.IMMUTABLE), false).reduce(0, (a, c) -> a + c); }
źródło
Użyj poniższego kodu, aby znaleźć liczbę dopasowań znalezionych przez wyrażenie regularne w danych wejściowych
Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);// "regex" here indicates your predefined regex. Matcher m = p.matcher(pattern); // "pattern" indicates your string to match the pattern against with boolean b = m.matches(); if(b) count++; while (m.find()) count++;
Jest to jednak kod uogólniony, a nie konkretny, dostosuj go do swoich potrzeb
Prosimy o poprawienie mnie, jeśli jest jakiś błąd.
źródło