it-swarm.it

conteggio delle giunzioni regex

Diciamo che ho un file e il file contiene questo:

HelloxxxHelloxxxHello

Compilo un modello per cercare "Ciao"

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

Quindi uso un inputstream per leggere il file e convertirlo in una stringa in modo che possa essere regexato.

Una volta che il matcher trova una corrispondenza nel file, indica questo, ma non mi dice quante corrispondenze ha trovato; semplicemente che ha trovato una corrispondenza all'interno della stringa.

Quindi, poiché la stringa è relativamente breve e il buffer che sto usando è 200 byte, dovrebbe trovare tre corrispondenze. Comunque, dice semplicemente match, e non mi fornisce un conteggio di quante partite ci sono state.

Qual è il modo più semplice per contare il numero di corrispondenze che si sono verificate all'interno della stringa. Ho provato vari loop per e usando matcher.groupCount () ma non sto andando da nessuna parte velocemente.

77
Tony

matcher.find() non trova corrispondenze all, solo la corrispondenza next.

Dovrai fare quanto segue:

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

Btw, matcher.groupCount() è qualcosa di completamente diverso.

Esempio completo :

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

Gestire le partite sovrapposte

Quando si contano le corrispondenze di aa in aaaa, lo snippet sopra riportato vi darà 2 .

aaaa
aa
  aa

Per ottenere 3 partite, ad esempio questo comportamento:

aaaa
aa
 aa
  aa

Devi cercare una corrispondenza all'indice <start of last match> + 1 come segue:

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

Questo dovrebbe funzionare per partite non disgiunte:

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

Questo può aiutare:

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

Se vuoi utilizzare stream Java 8 e sei allergico ai loop while, puoi provare questo:

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

Disclaimer: funziona solo per le partite disgiunte.

Esempio:

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

Questo stampa:

2
0
1
0

Questa è una soluzione per le partite disgiunte con i flussi:

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