[java] 정규식에 대한 일치 수를 어떻게 계산할 수 있습니까?

이것을 포함하는 문자열이 있다고 가정 해 봅시다.

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++;

Btw 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 를 제공합니다 .

aaaa
aa
  aa

3 개 일치를 얻으려면, 즉이 동작 :

aaaa
aa
 aa
  aa

<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


답변

이것은 겹칠 수있는 일치에 대해 작동합니다.

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++;

이것은 특정 코드가 아닌 일반화 된 코드이므로 필요에 맞게 조정하십시오.

실수가 있으면 언제든지 수정 해주세요.


답변