Différence entre matches () et find () dans Java Regex
Je suis en train d'essayer de comprendre la différence entre matches()
et find()
.
Selon le Javadoc, (d'après ce que je comprends), matches()
recherchera la chaîne entière même s'il trouve ce qu'il cherche, et find()
s'arrêtera quand il trouvera ce qu'il cherche.
Si cette hypothèse est correcte, je ne peux pas voir chaque fois que vous voulez utiliser matches()
au lieu de find()
, sauf si vous voulez compter le nombre de correspondances qu'il trouve.
À mon avis la classe String devrait alors avoir find()
au lieu de matches()
comme méthode intégrée.
Donc, pour résumer:
- Mon hypothèse est-elle correcte?
- Quand est-il utile d'utiliser
matches()
au lieu defind()
?
5 answers
matches
essaie de faire correspondre l'expression à la chaîne entière et ajoute implicitement un ^
au début et $
à la fin de votre modèle, ce qui signifie qu'il ne cherchera pas de sous-chaîne. D'où la sortie de ce code:
public static void main(String[] args) throws ParseException {
Pattern p = Pattern.compile("\\d\\d\\d");
Matcher m = p.matcher("a123b");
System.out.println(m.find());
System.out.println(m.matches());
p = Pattern.compile("^\\d\\d\\d$");
m = p.matcher("123");
System.out.println(m.find());
System.out.println(m.matches());
}
/* output:
true
false
true
true
*/
123
est une sous-chaîne de a123b
si le find()
méthode sorties de vrai. matches()
seulement 'voit' a123b
, qui n'est pas le même que 123
et donc renvoie false.
matches
renvoie true si la chaîne entière correspond au modèle donné. find
essaie de trouver une chaîne qui correspond au modèle.
matches()
ne retournera true que si la chaîne complète est mise en correspondance.
find()
va essayer de trouver la prochaine occurrence dans la sous-chaîne qui correspond à l'expression régulière. Notez l'accent mis sur "le prochain". Cela signifie que le résultat de l'appel de find()
plusieurs fois pourrait ne pas être le même. De plus, en utilisant find()
, vous pouvez appeler start()
pour renvoyer la position à laquelle la sous-chaîne a été appariée.
final Matcher subMatcher = Pattern.compile("\\d+").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + subMatcher.matches());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find());
System.out.println("Found: " + subMatcher.find());
System.out.println("Matched: " + subMatcher.matches());
System.out.println("-----------");
final Matcher fullMatcher = Pattern.compile("^\\w+$").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + fullMatcher.find() + " - position " + fullMatcher.start());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
Affichera:
Found: false Found: true - position 4 Found: true - position 17 Found: true - position 20 Found: false Found: false Matched: false ----------- Found: true - position 0 Found: false Found: false Matched: true Matched: true Matched: true Matched: true
Donc, soyez prudent lorsque vous appelez find()
plusieurs fois si l'objet Matcher
n'a pas été réinitialisé, même lorsque l'expression régulière est entourée de ^
et $
pour correspondre à la chaîne complète.
find()
considérera la sous-chaîne par rapport à l'expression régulière où as matches()
considérera l'expression complète.
find()
will renvoie true uniquement si la sous-chaîne de l'expression correspond au motif.
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d");
String candidate = "Java123";
Matcher m = p.matcher(candidate);
if (m != null){
System.out.println(m.find());//true
System.out.println(m.matches());//false
}
}
matches();
ne met pas en mémoire tampon, mais find()
en mémoire tampon. find()
recherche d'abord la fin de la chaîne, indexe le résultat et renvoie la valeur booléenne et l'index correspondant.
C'est pourquoi lorsque vous avez un code comme
1:Pattern.compile("[a-z]");
2:Pattern.matcher("0a1b1c3d4");
3:int count = 0;
4:while(matcher.find()){
5:count++: }
À 4: Le moteur regex utilisant la structure de modèle lira l'ensemble de votre code (index à index comme spécifié par le regex[single character]
pour trouver au moins une correspondance. Si une telle correspondance est trouvée, elle sera indexée puis la boucle s'exécutera en fonction du résultat indexé sinon s'il n'a pas fait de calcul anticipé comme ce qui matches()
; ne le fait pas. L'instruction while ne s'exécutera jamais car le premier caractère de la chaîne correspondante n'est pas un alphabet.