2017-01-29 3 views
1

Mein Text des folgenden Format:regex - diesen Teil passen nur, wenn die vorherigen Teil angepasst

<command>,<cabinet>,<drawer>,<report> 

Regeln sind:

<command>: 3-stellige Buchstaben nur,
<cabinet>: 1-4 stellige numeric,
<drawer>: 1 stellige alphanumerische zwischen A bis I,
<report>: 1-4 stelliges numerische

Jedes Segment ist nur sinnvoll, wenn das vorherige existiert. Kann annehmen, dass der Schrank immer vorhanden ist, sonst ist es einfach nicht nützlich, den Befehl zu finden.

Beispiel:

SRH,898 
SRH,898,G 
SRH,898,G,900 

Non Beispiel:

SRH,,,898   // <report> without <cabinet> or <drawer> 
SRH,898,,900  // <report> without <drawer>. Take only upto SRH,898 .. ignoring the rest 

Ich kam auf diese: [a-z$]{3},\d{1,4},([a-i])?(,\d+)?

Problem:
Fälle wie SRH,898,,900 mit dieser Regex gültig sind, während Idealerweise sollte es ungültig sein, wie <report> (900) existiert ohne <drawer>. Ich will es versuchen und Spiel für die <report>nur, wenn<drawer> vorhanden ist, wobei in diesem Fall die <drawer> wird von einem , vom <report> getrennt werden, wenn <report> auch vorhanden ist.

Ich denke, ich kann dies in zwei Schleifen tun, die zweite würde hintereinander , -s herausfiltern, aber hatte gehofft, etwas Besseres kann getan werden.

Irgendwelche Hilfe?

Dank

Schluss aktualisieren: https://regex101.com/r/i7HnLf/3 ist das gute Zeug :) Vielen Dank für die Hilfe :)

+3

Ihr Muster stimmt nicht ganz mit den Anforderungen überein. Es muss etwas sein wie^^ [a-zA-Z0-9] {3} (?:, [0-9] {1,4} (?:, [A-Ia-i0-9] (?:, [0-9] {1,4})?)?)? $ –

+0

@ WiktorStribiżew Ich denke, du warst verwirrt durch den alphanumerischen Teil. Mein Fehler, ich habe den Text etwas modifiziert. Befehl ist nur Buchstaben, keine Zahlen. Danke :) – Somjit

+0

@Somjit: einfach verwenden - '^ [a-zA-Z] {3} (?:, \ D {1,4} (?:, [A-iA-I] (?:, \ D {1,4})?)?)? $ – GurV

Antwort

0

Auch wenn es Ihnen gelingt, mit einem regulären Ausdruck zu kommen, das tut, was Sie wollen, also halten Zustand der zuvor angeglichenen Segmente, wird es nahezu unmöglich sein, zu warten.

Da Sie jede Datei öffnen und analysieren, sollten Sie Ihre Anforderungen in Ihrem Code besser behandeln.

+0

Ich verwende den Code für 'gültige' Ereignisse. Etwa 400 einzelne Dateien mit jeweils mehr als 1000 Zeilen Assembler-ähnlicher Syntax. Regex ist meine beste Hoffnung, denn die Sprache an sich ist ein altes Zeug und hat keine ähnliche Möglichkeit. – Somjit

+0

@Somjit die Tatsache, dass Sie Tausende von Zeilen zu lesen haben, ist kein guter Grund - der Code wird sich gleich auf einer Zeile oder Tausenden von Zeilen verhalten. Und wenn das hier das Problem ist, wird eine Lösung mit Regex wahrscheinlich langsamer und schwerer zu lesen/zu warten sein. Tun Sie es direkt über Code, weniger Schmerzen mehr Gewinn. – BackSlash

+4

@JChrist Ich denke, das sollte ein Kommentar sein – BackSlash

0

der folgende Code die Arbeit machen:

public class FourpartsRegEx { 

    static Pattern pattern = Pattern.compile(
     "([A-za-z]{3})" + // <command> : 3 digit letters only, 
     "(,"   + 
     "(\\d{1,4})" + // <cabinet> : 1-4 digit numeric, 
     "(,"   + 
     "([A-I])"  + // <drawer> : 1 digit alphanumeric between A to I, 
     "(,"   + 
     "(\\d{1,4})" + // <report> : 1-4 digit numeric 
     ")?)?)?" + 
     "" 
    ); 

    static void test(String expr) { 
     final Matcher m = pattern.matcher(expr); 
     if(m.matches()) { 
     System.err.printf("%s match ==> %s, %s, %s, %s\n", 
      expr, m.group(1), m.group(3), m.group(5), m.group(7)); 
     } 
     else { 
     System.err.printf("%s doesn't match\n", expr); 
     } 
    } 

    public static void main(String[] args) { 
     // Matches 
     test("SRH,898"); 
     test("SRH,898,G"); 
     test("SRH,898,G,900"); 

     // Non Matches 
     test("SRH,,,898" ); // <report> without <cabinet> or <drawer> 
     test("SRH,898,,900"); // <report> without <drawer> 
    } 
} 

Ausführung:

SRH,898 match ==> SRH, 898, null, null 
SRH,898,G match ==> SRH, 898, G, null 
SRH,898,G,900 match ==> SRH, 898, G, 900 
SRH,,,898 doesn't match 
SRH,898,,900 doesn't match 
+0

Schöne Weise zu drucken gibt. Obwohl mein Regex-Problem gelöst wurde, half mir dein Code, mir einige Ideen zu geben :) Danke :) – Somjit

+0

http: // stackoverflow.com/users/2715083/somjit Vergiss nicht, diese Antwort zu akzeptieren ;-) – Aubin

-1

prüfen diese regex:

^([^,][^,]*)($|,([^,][^,]*))($|,([^,][^,]*))($|,([^,][^,]*)) 

von Anfang an ein Token mit mindestens 1 nicht suchen , , gefolgt von einer Zeilenendung, oder a, gefolgt von einer anderen Zeichenfolge von mindestens 1 nicht, und so weiter ..

mit Beispielen auf http://regex101.com/ getestet und es scheint ...

EDIT zu arbeiten: sicher, die Regeln der Token sind noch nicht angewendet - denken Sie in der Lage sein wird, dies selbst zu tun ...

+0

jetzt optimiert: ^ ([AZ] {3} ($ |, (\ d {1,4})) ($ |, ([AI] *)) ($ |, (\ d +)) (Betrachte die Großbuchstaben bei der Eingabe von Großbuchstaben !!) –

+0

es heißt Musterfehler, aber danke – Somjit

+0

argh - fehlende Klammer auf Position 10 nach dem ersten Token in der optimierten Variante: ^ ([AZ] {3}) ($ |, (\ d {1,4})) ($ |, ([AI] *)) ($ |, (\ d +)) –