2010-12-15 5 views
178

Ich versuche, den Unterschied zwischen matches() und find() zu verstehen.Unterschied zwischen Übereinstimmungen() und find() in Java Regex

Nach dem Javadoc, (von dem, was ich verstehe), matches() wird die gesamte Zeichenfolge suchen, auch wenn es findet, wonach es sucht, und find() wird aufhören, wenn es findet, wonach es sucht.

Wenn diese Annahme korrekt ist, kann ich nicht sehen, wann Sie matches() anstelle von find() verwenden möchten, es sei denn, Sie möchten die Anzahl der gefundenen Übereinstimmungen zählen.

Meiner Meinung nach sollte die String-Klasse dann find() anstelle von matches() als integrierte Methode haben.

  1. Stimmt meine Annahme:

    So zusammenzufassen?

  2. Wann ist es sinnvoll, matches() anstelle von find() zu verwenden?
+2

Beachten Sie, dass das mehrfache Aufrufen von 'find()' zu unterschiedlichen Ergebnissen für den gleichen 'Matcher' führen kann. Siehe meine Antwort unten. –

Antwort

226

matches versucht, den Ausdruck gegen die gesamte Zeichenfolge übereinstimmen und implizit eine ^ am Anfang und $ am Ende Ihres Muster hinzufügen, es wird nicht nach einer Teil aussehen bedeutet. Daraus ergibt sich die Ausgabe dieses 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 ist eine Teilkette von a123b so die find() Methode Ausgänge wahr. matches() nur "sieht" a123b was ist nicht das gleiche wie 123 und gibt daher false aus.

+12

Diese Antwort ist irreführend. 'matchers()' ist nicht einfach ein 'find()' mit implizierter Umgebung^und $. Beachten Sie, dass der Aufruf von '.find()' mehr als einmal verschiedene Ergebnisse haben kann, wenn nicht 'reset()' vorangestellt ist, während 'matches()' immer das gleiche Ergebnis liefert. Siehe meine Antwort unten. –

61

geben Sie true zurück, wenn die gesamte Zeichenfolge mit dem angegebenen Muster übereinstimmt. find versucht, eine Teilzeichenfolge zu finden, die mit dem Muster übereinstimmt.

+27

Man könnte sagen, dass 'matches (p)' dasselbe ist wie 'find ("^"+ p +" $ ")' wenn das etwas klarer ist. – jensgram

+3

Nur ein Beispiel, um die Antwort zu klären: "[a-z] +" mit der Zeichenfolge "123abc123" schlägt mit matchs() fehl, ist aber erfolgreich mit find(). – bezmax

+3

@Max Genau, '" 123abc123 ".matches (" [a-z] + ")' wird genauso scheitern wie '" 123abc123 ".find ("^[a-z] + $ ")' würde. Mein Punkt war, dass 'matches()' für eine komplette Übereinstimmung verwendet wird, genau wie 'find()' mit Start- und Endankern. – jensgram

34

matches() werden nur wahr zurückgegeben, wenn die vollständige Zeichenfolge übereinstimmt. find() wird versuchen, das nächste Auftreten in der Teilzeichenfolge zu finden, die die Regex entspricht. Beachten Sie die Betonung auf "die nächste". Das heißt, das Ergebnis des mehrmaligen Aufrufs von find() ist möglicherweise nicht dasselbe. Mit find() können Sie außerdem start() aufrufen, um die Position zurückzugeben, an der die Teilzeichenfolge gefunden wurde.

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

Will Ausgang:

 
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 

Also, seien Sie vorsichtig, wenn find() mehrmals aufrufen, wenn das Matcher Objekt nicht zurückgesetzt wurde, auch wenn die Regex mit ^ und $ umgeben ist die vollständige Zeichenfolge übereinstimmen.

2

matches(); puffert nicht, aber find() Puffer. find() sucht das Ende der Zeichenfolge zuerst, indiziert das Ergebnis und gibt den booleschen Wert und den entsprechenden Index zurück.

Deshalb ist, wenn Sie einen Code wie

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

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

3:int count = 0; 

4:while(matcher.find()){ 

5:count++: } 

Bei 4: Die Regex-Engine die Musterstruktur verwendet, wird durch den gesamten Code (Index zu Index gelesen, wie durch die regex[single character] angegeben Finden Sie mindestens eine Übereinstimmung.Wenn eine solche Übereinstimmung gefunden wird, wird sie indiziert, dann wird die Schleife basierend auf dem indizierten Ergebnis ausgeführt, andernfalls, wenn sie keine Vorausberechnung durchführt, wie das matches() nicht tut. Die while-Anweisung würde niemals ausgeführt werden Das erste Zeichen der übereinstimmenden Zeichenfolge ist kein Alphabet

2

find() berücksichtigt die Unterzeichenfolge für den regulären Ausdruck, wobei matches() den vollständigen Ausdruck berücksichtigt.

find() gibt nur dann true zurück, wenn die Unterzeichenfolge des Ausdrucks mit dem Muster übereinstimmt.

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