Скажем, у меня есть строка, содержащая это:
HelloxxxHelloxxxHello
Я составляю шаблон для поиска "Hello"
Pattern pattern = Pattern.compile("Hello");
Matcher matcher = pattern.matcher("HelloxxxHelloxxxHello");
Должно быть найдено три спички. Как я могу подсчитать, сколько было совпадений?
Я пробовал разные циклы и использовал, matcher.groupCount()
но это не сработало.
Ответы:
matcher.find()
не находит все совпадения, только следующее совпадение.Решение для Java 9+
long matches = matcher.results().count();
Решение для Java 8 и старше
Вам нужно будет сделать следующее. ( Начиная с Java 9 есть более приятное решение )
int count = 0; while (matcher.find()) count++;
Кстати,
matcher.groupCount()
совсем другое дело.Полный пример :
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 } }
Обработка совпадающих матчей
При подсчете совпадений
aa
вaaaa
приведенном выше фрагменте вы получите 2 .Чтобы получить 3 совпадения, то есть такое поведение:
Вы должны искать совпадение по индексу
<start of last match> + 1
следующим образом: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
источник
while(matcher.find()){ matcher.region(matcher.end()-1, str.length()); count++; }
Это должно работать для совпадений, которые могут перекрываться:
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); }
источник
Из Java 9 вы можете использовать поток, предоставляемый
Matcher.results()
long matches = matcher.results().count();
источник
Если вы хотите использовать потоки Java 8 и у вас аллергия на
while
циклы, вы можете попробовать следующее: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(); }
Отказ от ответственности: это работает только для непересекающихся совпадений.
Пример:
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)); }
Это распечатывает:
2 0 1 0
Это решение для непересекающихся совпадений с потоками:
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); }
источник
Используйте приведенный ниже код, чтобы найти количество совпадений, которые регулярное выражение находит во входных данных.
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++;
Это обобщенный код, а не конкретный, адаптируйте его под свои нужды.
Пожалуйста, не стесняйтесь поправлять меня, если есть ошибка.
источник