2012-03-27 4 views
1

Ich mache eine Musterübereinstimmung in einem Stück Code, der in einem Umstand, aber nicht in einem anderen gut funktioniert. Der Code ist zur Zeit:Debugging-Muster (Regex) Fehler in Java (Android)

DLVRYrx = Pattern.compile("(\\d+\\s\\p{Letter}+\\s\\d+)\\s(\\d+(?:\\.\\d+)?)\\s(\\d+)"); 
Log.d(TAG, "* Regex matched " + DLVRYrx.matcher("01 Jan 01 60.9876 1234").groupCount() + " groups"); // prints 3 as expected in logcat 
for (int i=19; i<(fields-6); i++) { 
    final String DATAstr = values[i]; 
    try { 
     Matcher Dmatch = DLVRYrx.matcher(DATAstr); 
     String data1 = Dmatch.group(0); 
    } catch (IllegalStateException e) { 
     Log.e(TAG, "! Text ["+DATAstr+"] didn't match regex"); 
    } 
} 

Der Code führt Illegal auf dem Dmatch.group (0) Linie. Die Ausgabe der Logcat-Zeile aus dem Catch ist "01 Jan 01 60.9876 1234" wie oben.

Das Ausführen eines Hexdumps in der Datendatei, die ich einlese, zeigt, dass die Leerzeichen Leerstellen sind, wie erwartet, und keine zufälligen Zeichen vor oder nach dem übereinstimmenden Text. Irgendwelche Vorschläge zum Debuggen?

Ich habe ein bisschen Code geändert, nur um meinen Ausdruck selbst zu testen, und jetzt bin ich mehr verwirrt. Innerhalb der Schleife bin ich überprüft jetzt, ob der String dem Muster übereinstimmt zuerst, dann über die kompilierte Version ausgeführt wird:

Pattern P = Pattern.compile(DLVRYrxStr); 
if(!DATAstr.matches(DLVRYrxStr)) { 
    Log.e(TAG, "[" + DATAstr + "] doesn't match regex"); 
    break; 
} 
Matcher Dmatch = P.matcher(DATAstr); 

Leider ist das Muster entspricht, und fällt damit bis zum P (?) .matcher Linie, die Linie nach dem wirft eine Ausnahme, wenn ich versuche, die erste passende Gruppe zu lesen:

W/System.err(1238): java.lang.IllegalStateException: No successful match so far 
W/System.err(1238): at java.util.regex.Matcher.ensureMatch(Matcher.java:607) 
W/System.err(1238): at java.util.regex.Matcher.group(Matcher.java:358) 

Lösung ist „.matches()“ überprüfen, wie unten hinzufügen:

Matcher Dmatch = DLVRYrx.matcher(DATAstr); 
Dmatch.matches(); 
String data1 = Dmatch.group(0); 

Ja Ich benutze das in einer 'if' Anweisung in meinem Code, aber es frei hängen zu lassen funktioniert wie oben.

+0

http://myregexp.com/signedJar.html ist wirklich nützlich beim Erstellen von Regexes, kann Sie Gruppen markieren, Kopieren von/nach Java-Syntax usw. – zapl

+0

Wie gesagt, die Regex arbeitet an der Beispiel-String explizit im Code gegeben. Es funktioniert nur nicht mit der (gleichen) Zeichenfolge, die von einer Datei analysiert wird. Außerdem verwende ich den Regex-Tester von Brosinski für Eclispe. – mikebabcock

+0

Aktualisierung von Android SDK (eine Version dahinter scheint), nur für den Fall. – mikebabcock

Antwort

4

Ihre DLVRYrx.matcher(...).groupCount() sagt Ihnen einfach, dass es in dem Muster, aus dem es erstellt wurde, drei übereinstimmende Gruppen gibt.

heißt (\\d+\\s\\p{Letter}+\\s\\d+), (\\d+(?:\\.\\d+) und (\\d+)

Sie müssen rufen entweder

matcher.matches()

matcher.lookingAt()

oder

matcher.find()

Vor dem Versuch, matcher.group(0) zu erhalten, da diese Methoden Java zur Analyse der Zeichenfolge auffordern.

+0

Siehe meine bearbeitete Version oben; das Spiel funktioniert. p {L} und p {Letter} sind äquivalent und werden für "jeden beliebigen Buchstaben in Unicode" verwendet. Sie arbeiten auch mit "Matches". – mikebabcock

+0

Getestet auch ersetzt alle 'p {Letter}' mit 'w' ... gleichen Fehler. – mikebabcock

+0

@mikebabcock Tut mir leid, ich habe das vorher nicht gesehen - siehe updates - auch nachdem du deinen 'Matcher' erstellst und bevor du' matcher.group (0) 'bekommst, musst du' matcher.matches() 'ausführen . Probieren Sie das aus. – Shaded