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 la Javadoc, (ce que je comprends), matches() recherchera l'ensemble de la chaîne, même si elle trouve ce qu'elle cherche, et find() va s'arrêter quand il trouve ce qu'il cherche.

Si cette hypothèse est correcte, Je ne peux pas voir quand 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:

  1. mon hypothèse est-elle correcte?
  2. Quand est-il utile d'utiliser matches() au lieu de find()?
197
demandé sur evandrix 2010-12-15 15:50:32

5 réponses

matches essaie de faire correspondre l'expression à la chaîne entière et ajoute implicitement un ^ au début et $ à la fin de votre motif, 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.

253
répondu Sanjay T. Sharma 2013-07-26 14:48:23

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

64
répondu khachik 2010-12-15 12:53:15

matches() ne retournera true que si la chaîne complète est mise en correspondance. {[3] } va essayer de trouver La prochaine occurrence dans la sous-chaîne qui correspond à l'expression rationnelle. Remarque l'accent sur "le prochain". Cela signifie que le résultat de l'appel de find() plusieurs fois peut ne pas être le même. De plus, en utilisant find() vous pouvez appeler start() pour renvoyer la position de la sous-chaîne correspondante.

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 rationnelle est entourée de ^ et $ pour correspondre à la chaîne complète.

40
répondu L. Holanda 2013-08-23 18:00:58

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
        }
    }
3
répondu Sumanth Varada 2017-02-10 09:39:48

matches(); ne met pas en mémoire tampon, mais find() met 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 motif 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 alors la boucle s'exécutera basé sur le résultat indexé sinon s'il n'a pas fait de calcul anticipé comme matches(); ne le fait pas. L'instruction while ne s'exécuterait jamais puisque le premier caractère de la chaîne correspondante n'est pas un alphabet.

2
répondu 2016-03-15 21:36:45