web-dev-qa-db-fra.com

Différence entre matches () et find () dans Java Regex

J'essaie de comprendre la différence entre matches() et find() .

D'après le Javadoc, (d'après ce que j'ai compris), matches() recherchera toute la chaîne, même s'il trouve ce qu'il cherche, et find() s'arrêtera lorsqu'il trouvera ce qu'il cherche.

Si cette hypothèse est correcte, je ne peux pas voir à chaque fois que vous voudriez utiliser matches() au lieu de find(), à moins que vous ne vouliez compter le nombre de correspondances trouvées.

À mon avis, la classe String devrait alors avoir find() au lieu de matches() en tant que méthode intégrée.

Donc, pour résumer:

  1. Est-ce que mon hypothèse est correcte?
  2. Quand est-il utile d'utiliser matches() au lieu de find()?
226
Shervin Asgari

matches essaie de faire correspondre l'expression à la chaîne entière et ajoute implicitement un ^ au début et un $ à 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 donc la méthode find() renvoie true. matches() uniquement 'voit' a123b qui n'est pas identique à 123 et génère donc la valeur false.

277
Sanjay T. Sharma

matches renvoie true si la chaîne entière correspond au modèle donné. find essaie de trouver une sous-chaîne correspondant au motif.

74
khachik

matches() ne retournera true que si la chaîne complète est vérifiée. find() essaiera de trouver la prochaine occurrence dans la sous-chaîne qui correspond à la regex. Notez l'accent sur "le prochain". Cela signifie que le résultat de l'appel de find() plusieurs fois peut ne pas être identique. De plus, en utilisant find(), vous pouvez appeler start() pour renvoyer la position correspondant à la sous-chaîne.

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

Est-ce que la sortie:

 Trouvé: faux 
 Trouvé: vrai - position 4 
 Trouvé: vrai - position 17 
 Trouvé: vrai - position 20 
 Trouvé: faux 
 Trouvé: faux 
 Correspondant: faux 
 ----------- 
 Trouvé: vrai - position 0 
 Trouvé: faux 
 Trouvé: false 
 Correspondant: vrai 
 Correspondant: vrai 
 Correspondant: vrai 
 Correspondant: vrai 

Par conséquent, soyez prudent lorsque vous appelez find() plusieurs fois si l'objet Matcher n'a pas été réinitialisé, même si l'expression régulière est entourée de ^ et $ pour correspondre à la chaîne complète.

52
L. Holanda

find() considérera la sous-chaîne par rapport à l'expression régulière alors que matches() considérera une expression complète.

find() ne renvoie true que si la sous-chaîne de l'expression correspond au modèle.

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
        }
    }
5
Sumanth Varada

matches(); ne met pas en tampon, mais find() tampons. find() cherche tout 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 quand vous avez un code comme

1:Pattern.compile("[a-z]");

2:Pattern.matcher("0a1b1c3d4");

3:int count = 0;

4:while(matcher.find()){

5:count++: }

At 4: Le moteur des expressions rationnelles utilisant la structure de modèle lira l'intégralité 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 sera exécutée sur la base du résultat indexé sinon, si elle ne fait pas de calcul en avant comme ce que matches(); ne fait pas. L’instruction while ne s’exécutera jamais puisque le premier caractère de la chaîne correspondante est pas un alphabet.

3
user5767743