2009-12-12 5 views
16

Aus meinem Verständnis von regulären Ausdrücken muss die Zeichenfolge "00 ###" mit "[0-9]" übereinstimmen, aber nicht mit "^ [0-9] $". Aber es funktioniert nicht mit Java Regexp's.

Nach einiger Untersuchung dieses Problems fand ich die folgenden Informationen (http://www.wellho.net/solutions/java-regular-expressions-in-java.html):

Es könnte scheinen, dass reguläre Java- Ausdrücke werden standardmäßig verankert mit sowohl ein^und $ -Zeichen.

Können wir sicher sein, dass dies für alle Versionen von JDK gilt? Und kann dieser Modus deaktiviert werden (d. H. Um die Standardverankerung mit^und $ zu deaktivieren)?

Antwort

21

Wie der Artikel, den Sie verlinkt haben, erklärt, hängt es von der Funktion ab, die Sie anrufen. Wenn Sie standardmäßig^und $ hinzufügen möchten, verwenden Sie String#matches oder Matcher#matches. Wenn Sie das nicht möchten, verwenden Sie stattdessen die Methode Matcher#find.

import java.util.regex.*; 

public class Example 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("Matches: " + "abc".matches("a+")); 

     Matcher matcher = Pattern.compile("a+").matcher("abc"); 
     System.out.println("Find: " + matcher.find()); 
    } 
} 

Ausgang:

Matches: false 
Find: true 
+0

Dies ist nicht einzigartig für Java, BTW. Python, und ich glaube auch, JavaScript, haben einige Regex-Methoden, die standardmäßig ankern, und andere, die das nicht tun. –

+5

@Laurence: Die Methoden 'test()', 'exec()' und 'match()' von JavaScript funktionieren alle gleich: Wenn Sie möchten, dass die Übereinstimmung verankert wird, müssen Sie sie selbst verankern. Auf der anderen Seite funktioniert Pythons 'match()' Methode wie Javas 'lookingAt()'; Die Übereinstimmung wird am Anfang der Zeichenfolge verankert, aber nicht bis zum Ende. –

3

Neben Mr. Byers's answer, beachten Sie auch, dass Matcher#find() beginnt dort, wo sein letztes erfolgreiches Spiel aufhörte. Das ist nur für die wiederholte Verwendung einer Matcher Instanz wichtig, aber das ist die Funktion, die die Emulation von Perls \G Assertion ermöglicht. Es ist auch nützlich in Verbindung mit Matcher#usePattern(Pattern), wo Sie ein Muster verwenden, um ein Präfix zu finden und dann in einem sich wiederholenden Muster (einschließlich \G) zu tauschen, um wiederholte Übereinstimmungen mit Matcher#find() zu wiederholen.

Es gibt auch Matcher#lookingAt(), die implizit am Anfang (^) implizit begrenzt ist, aber nicht am Ende. Ich denke lieber, dass der Name von der Emacs-Funktion looking-at inspiriert wurde.

3

Ja, matches() wirkt immer so, als wäre die Regex an beiden Enden verankert. Um das traditionelle Verhalten zu erhalten, das mit einer Teilzeichenkette des Zielobjekts übereinstimmt, müssen Sie find() verwenden (wie bereits erwähnt). Sehr wenige Regex-Tools bieten alles, was zu Javas matches() Methoden äquivalent ist, so dass Ihre Verwirrung gerechtfertigt ist. Der einzige andere, an den ich denken kann, ist der XML Schema Geschmack.