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.
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
}
}
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
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);
}
Cela peut aider:
public static void main(String[] args) {
String hello = "HelloxxxHelloxxxHello";
String []matches = hello.split("Hello");
System.out.println(matches.length); // prints 3
}
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);
}