web-dev-qa-db-fra.com

nombre de correspondances java regex

Disons que j'ai un fichier, et le fichier contient ceci:

HelloxxxHelloxxxHello

Je compile un motif pour rechercher 'Bonjour'

Pattern pattern = Pattern.compile("Hello");

Ensuite, j'utilise un flux d'entrée pour lire le fichier et le convertir en chaîne afin qu'il puisse être regexé.

Une fois que le matcher a trouvé une correspondance dans le fichier, il l'indique, mais il ne m'indique pas le nombre de correspondances qu'il a trouvées; simplement qu'il trouve une correspondance dans la chaîne.

Donc, comme la chaîne est relativement courte et que le tampon que j'utilise est de 200 octets, il devrait trouver trois correspondances. Cependant, cela dit simplement correspondance, et ne me donne pas le nombre de correspondances.

Quel est le moyen le plus simple de compter le nombre de correspondances qui se sont produites dans la chaîne. J'ai essayé diverses boucles for et l'utilisation de matcher.groupCount () mais je ne vais nulle part rapidement.

77
Tony

matcher.find() ne trouve pas les correspondances all, seule la correspondance next.

Vous devrez faire ce qui suit:

int count = 0;
while (matcher.find())
    count++;

Btw, matcher.groupCount() est quelque chose de complètement différent.

Exemple complet :

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
    }
}

Traitement des correspondances qui se chevauchent

Lorsque vous comptez des correspondances de aa dans aaaa, l'extrait ci-dessus vous donnera 2 .

aaaa
aa
  aa

Pour obtenir 3 correspondances, c’est-à-dire ce comportement:

aaaa
aa
 aa
  aa

Vous devez rechercher une correspondance à l’index <start of last match> + 1 comme suit:

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
149
aioobe

Cela devrait fonctionner pour les correspondances non disjointes:

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);
}
14
Mary-Anne Wolf

Cela peut aider:

public static void main(String[] args) {
    String hello = "HelloxxxHelloxxxHello";
    String []matches = hello.split("Hello");
    System.out.println(matches.length);    // prints 3
}
0
majid zareei

Si vous souhaitez utiliser les flux Java 8 et êtes allergique aux boucles while, essayez ceci:

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();
}

Avertissement: cela ne fonctionne que pour les matchs disjoints.

Exemple:

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));
}

Cela imprime:

2
0
1
0

C'est une solution pour les correspondances disjointes avec les flux:

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);
}
0
gil.fernandes