2016-07-20 34 views
0

Ich habe versucht Regex zu verwenden, um Daten aus der Ausgabe zu analysieren, die durch den Standard-Ping-Befehl gesammelt wurde. Einige Muster funktionieren jedoch nicht wie erwartet, selbst nachdem der Regex-Ausdruck in Online-Regex-Prüfern überprüft wurde (sie funktionieren im Browser gut).Java Regex Matcher zeigt unerwartete Ergebnisse

Der Fehler war ich erhielt wie folgt:

Exception in thread "main" java.lang.IllegalStateException: No match found 
    at java.util.regex.Matcher.group(Matcher.java:536) 
    at RegexMatches.parseGroupBytes(RegexMatches.java:77) 
    at RegexMatches.main(RegexMatches.java:13) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

Process finished with exit code 1 

, dass ich Erfahrung fehlt mit Regex gegeben, würde ich gerne wissen, wie, um fortzufahren, um das Problem zu beheben. Die Klasse I verwendet wird, ist wie folgt:

public class RegexMatches 
{ 
    public static void main(String args[]){ 
     String input = "[1463895254]PING www.andi.dz (213.179.181.44) 100(128) bytes of data.[1463895254]108 bytes from 213.179.181.44: icmp_seq=1 ttl=54 time=195 ms[1463895255]108 bytes from 213.179.181.44: icmp_seq=2 ttl=54 time=202 ms[1463895256]108 bytes from 213.179.181.44: icmp_seq=3 ttl=54 time=180 ms[1463895257]108 bytes from 213.179.181.44: icmp_seq=4 ttl=54 time=200 ms[1463895258]108 bytes from 213.179.181.44: icmp_seq=5 ttl=54 time=206 ms[1463895259]108 bytes from 213.179.181.44: icmp_seq=6 ttl=54 time=188 ms[1463895260]108 bytes from 213.179.181.44: icmp_seq=7 ttl=54 time=182 ms[1463895261]108 bytes from 213.179.181.44: icmp_seq=8 ttl=54 time=223 ms[1463895263]108 bytes from 213.179.181.44: icmp_seq=9 ttl=54 time=187 ms[1463895263]108 bytes from 213.179.181.44: icmp_seq=10 ttl=54 time=199 ms"; 
     String input2 = "[1463895327]PING www.gov.bw (168.167.134.24) 100(128) bytes of data.[1463895327]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=1 ttl=110 time=868 ms[1463895328]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=2 ttl=110 time=892 ms[1463895329]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=3 ttl=110 time=814 ms[1463895330]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=4 ttl=110 time=1009 ms[1463895331]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=5 ttl=110 time=1006 ms[1463895332]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=6 ttl=110 time=984 ms[1463895333]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=7 ttl=110 time=1004 ms[1463895334]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=8 ttl=110 time=1006 ms[1463895335]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=9 ttl=110 time=1013 ms[1463895336]108 bytes from www.gov.bw (168.167.134.24): icmp_seq=10 ttl=110 time=578 ms[1463895336][1463895336]--- www.gov.bw ping statistics ---[1463895336]10 packets transmitted, 10 received, 0% packet loss, time 9007ms[1463895336]rtt min/avg/max/mdev = 578.263/917.875/1013.707/132.095 ms, pipe 2\n"; 
//  System.out.println(parse1(input)); 
     try{ 
      String op[] = parseGroupBytes(input); 
      System.out.println(op[0]); 
     } 
     catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public static String parse1(String input){ 
     Pattern p =Pattern.compile("\\[([0-9]{10})\\]PING"); 
     Matcher m = p.matcher(input); 
     if (m.find()) 
      return m.group(1); 
     else 
      return "error"; 
    } 

// Doesn't Work... 
    // patterns seem to be correct but only shows the first value 

    public static String[] parseGroupBytes(String input) throws BytesNotFoundException { 
     // Capture the bytes after (ip-address) outside the parenthesis 
     // Capture the bytes after (ip-address) inside the parenthesis 
     Pattern p1 = Pattern.compile("\\)\\s+(\\d+)\\("); 
     Matcher m1 = p1.matcher(input); 
     Pattern p2 = Pattern.compile("\\((\\d+)\\)\\s+bytes"); 
     Matcher m2 = p2.matcher(input); 
     String[] GroupBytes = new String[2]; 
     int x = m1.groupCount(); 
     int y = m2.groupCount(); 
     if(m1.find() || m2.find()){ 
      GroupBytes[0] = m1.group(1); 
      GroupBytes[1] = m2.group(1); 
       return GroupBytes; 
     } 
     else 
      throw new BytesNotFoundException(); 
    } 
} 
+0

'if (m1.find() || m2.find()) {' paaren helfen - ich glaube, 'm1' eine Übereinstimmung gefunden und' m2' nicht wirklich Ausführen nach "||". Führen Sie beide vor dem 'if' aus, weisen Sie sie bool-Variablen zu, und das sollte funktionieren. –

+0

Warum brechen Sie die Operation in zwei separate Übereinstimmungen? Suchen Sie einfach nach '" \\) \\ s + (\\ d +) \\ ((\\ d +) \\) \\ s + Bytes "' und extrahieren Sie 'Gruppe (1)' und 'Gruppe (2)'. –

Antwort

0

Sie m1.find() || m2.find() tun also, wenn m1 eine Übereinstimmung m2 findet, wird nicht versucht werden, so dass Sie es zum Beispiel ändern sollte zu zwei, wenn die Regex in ein einzelnes Muster überprüft oder zusammengeführt wird.

+0

Danke für die Antwort. Dies war beabsichtigt, um das Hauptproblem zu isolieren, das zur Laufzeit keine Übereinstimmungen hat, während Online-Regex-Prüfer mir sagen, dass das Muster korrekt ist. –

4

Problem ist dieser Block:

if(m1.find() || m2.find()){ 
    GroupBytes[0] = m1.group(1); 
    GroupBytes[1] = m2.group(1); 
    return GroupBytes; 
} 

Da Sie in if Zustand sind Eingabe, wenn eine der Treffer für m1 Matcher Erfolg haben oder m2 aber während m2.group(1) Ausführung wird es IllegalStateExceptionseit m2.find() werfen nie ausgeführt wird aufgrund von || und m1.find() wieder wahr.

ändern, die zu blockieren && anstelle von ||:

if(m1.find() && m2.find()){ 
    GroupBytes[0] = m1.group(1); 
    GroupBytes[1] = m2.group(1); 
    return GroupBytes; 
} 
else 
    throw new BytesNotFoundException(); 

Jetzt Code find() für beide Matcher auszuführen m1 und m2 vor .group(1) für jede Matcher Objekte aufrufen.

+0

Danke für die Antwort. Ja, du hast absolut recht, was du gesagt hast, aber ich denke, ich habe das Problem nicht deutlich genug erwähnt. Ich habe || benutzt statt && absichtlich (vorübergehend), um das eigentliche Problem zu isolieren. Mein Problem ist zur Laufzeit keine Übereinstimmungen zu bekommen, während ich von Regex-Checkern online bekomme, was ich will. –

+0

Der von Ihnen bereitgestellte Code funktioniert nach dem Ersetzen von '||' durch '&&' einwandfrei. Weiter, wenn Sie Ihren Code aktualisieren, der Ihr Problem reproduziert, kann ich überprüfen und schlagen – anubhava

0

public String-Gruppe (Gruppe int)

Gibt die Subsequenz Eingabe durch die gegebene Gruppe während der vorhergehenden Übereinstimmungsoperation eingefangen.

Problem ist, dass Sie auf m2 Matcher finden rufen Sie nicht ... versuchen, diese stattdessen

m1.find() | m2.find() 

Die Tatsache, dass Sie matches() als falsch zur Laufzeit ausgewertet, weil find() versucht, eine Teilfolge Ihrer Eingabe zu finden das entspricht dem Muster, während matches() den gesamten Eingang auswertet. Wenn Sie Ihr Beispiel mit matches() arbeiten wollen, dann sollten Sie das Muster ändern, wie

Pattern p1 = Pattern.compile("^.*\\)\\s+(\\d+)\\(.*$"); 
Matcher m1 = p1.matcher(input); 
Pattern p2 = Pattern.compile("^.*\\((\\d+)\\)\\s+bytes.*$"); 
Matcher m2 = p2.matcher(input); 
... 
if(m1.matches() && m2.matches()) 
//then store values of each matcher group. 

Sie können sogar die 2-Muster in 1 Einzelmuster neu zu gruppieren, die beide Ausdrücke P1 und P2 mit einer UND-Bedingung begrenzt ...

Pattern p1 = Pattern.compile("(?=^.*\\)\\s+(\\d+)\\(.*$)(?=^.*\\((\\d+)\\)\\s+bytes.*$).*$"); 

Hope this würden Sie :)

+0

Danke für die Antwort. Dies war beabsichtigt, um das Hauptproblem zu isolieren, das keine Übereinstimmungen zur Laufzeit hat, während Online-Regex-Checker mir sagen, das Muster ist korrekt –

+0

Ich habe die Antwort für Sie bearbeitet ... Ich hoffe, das ist die Antwort auf Ihr Problem :) –

+0

Entschuldigung aber das gibt Nullwerte zurück –