Java RegEx

#basTi

Commodore Pro
Registriert
Aug. 2005
Beiträge
4.765
Hallo zusammen,

ich benötige momentan für mein Programm ein paar RegEx Ausdrücke.
Hab mich schon nen ganzen Tag lang damit beschäftigt aber irgendwelche kleine Fehler sind immer drin :freak:

Wär toll, wenn ihr mir mit einem speziellen Ausdruck helfen könntet.

Es geht um folgendes Muster welches gematched werden müsste:
Text mit Sonderzeichen ( -3; -2 ) / More Text ( -1 ... +4 ) / Even More ( 5 )

Nochmal Textuell fürs Verständnis:
  • Als erstes kommt eine gewisse Zeichenfolge inkl Sonderzeichen (darf auch leer sein).
  • Darauf eine Offene Klammer.
  • In dieser Klammer steht entweder:
    • Eine Einzelne Zahl (mit plus oder minus Vorzeichen), darf auch float sein ( 3,44 )
    • Eine Liste von Zahlen getrennt durch Strichkommas
    • Zahlenbereich ( von ... bis ) getrennt durch drei Punkte
  • Geschlossene Klammer
  • Diese Liste kann sich n mal wiederholen, getrennt durch Slashes, mit n>0, d.h. es sind mindestens zwei Elemente vorhanden. D.h. nur "Text (2)" soll nicht matchen.

Mein aktueller Stand:
Code:
\s*[\w\W&&[^()]]+\(\s*[+-]?\s?[\d]+(,\d+)?\s*\)\s*(/\s*[\w\W&&[^()]]+\(\s*[+-]?\s?[\d]+(,\d+)?\s*\)\s*)*
Dieser matched zwar perfekt eine Liste von mehreren Elementen "a(1) / b(2) / ... / ..." aber nur wenn in der Klammer eine einzelne Zahl steht.
Ich weiss nicht, wie ich in der Klammer ein ODER hinbekomme: einzelne Zahl ODER Liste ODER Wertebereich.

Wäre über jede Hilfe dankbar! :)
 
Zuletzt bearbeitet:
http://regexpal.com/
Code:
(([\w\s\.\+\*]+\s?)\s?\(((\s?[-\+]?\d,?\s?)+|(\s?[-\+]?\d,?\s?)\.\.\.(\s?[-\+]?\d,?\s?))\)\s?\/\s?)+
Matcht aber bisher nur Text mit Sonderzeichen ( -3, -2 ) / More Text ( -1 ... +4 ) / . Vielleicht siehst du ja den Fehler.

edit:
`basTi schrieb:
Diese Liste kann sich n mal wiederholen, getrennt durch Slashes, mit n>0, d.h. es sind mindestens zwei Elemente vorhanden.
Mindestens zwei heißt aber > 1? Dann zum Ende + durch {2,} ersetzen.
`basTi schrieb:
D.h. nur "Text (2)" soll nicht matchen.
Also Even More( 5 ) nicht?
 
Zuletzt bearbeitet:
Yuuri schrieb:
Also Even More( 5 ) nicht?
Damit bezog ich mich nur auf die Länge nicht auf den Inhalt.

Also im Prinzip ist das Gesuchte eine Liste getrennt durch Slashes "/".
Diese Liste muss mindestens zwei Elemente beinhalten, d.h. es muss mind. ein Slash vorkommen und deswegen soll "Even more ( Inhalt )" nicht matchen.


Bei deiner Variante gibt es leider noch mehrere Fehler:
- ( 2 3 ) wird akzeptiert. Eine Liste in der Klammer muss aber durch Strichkommas getrennt werden (habe ich übrigens Editiert ... davor stand Kommas im ausgangspost)
- Deine Liste muss mit Slash Enden. Das soll sie aber nicht. Slashes sind nur zum separieren der Elemente.

Ich hoffe die Problemstellung ist n bisl klarer geworden :) . Wenn nicht nachfragen.

Eine Frage noch: Was bedeutet das "|" Zeichen in deiner RegEx?
//Edit: habs rausgefunden :D ... DAS ist das gesuchte ODER :)
Damits hab ichs hinbekommen:
Code:
\s*[\w\W&&[^()]]+\(\s*[+-]?\d+(,\d+)?\s*(\.\.\.\s*[+-]?\d+(,\d+)?|(;\s*[+-]?\d+(,\d+)?)+)?\s*\)\s*(/\s*[\w\W&&[^()]]+\(\s*[+-]?\d+(,\d+)?\s*(\.\.\.\s*[+-]?\d+(,\d+)?|(;\s*[+-]?\d+(,\d+)?)+)?\s*\)\s*)+

//Edit 2:

Bin nun auf ein neues RegEx Problem gestoßen:
Ich will den Ausdruck (den wir grad gematched haben) an den Slashes splitten. Mit einer Ausnahme: Slashes in eckigen Klammer sollen ignoriert werden.
Beispiel:
Text (1) / Text ( 1... 2) / text (3)

Dies ist noch simpel ;) Nächstes Beispiel:
Text [km/h] (1) / Text [m/s] ( 1... 2) / text (3)

Ich hab sogar schon den richtigen Regulären Ausdruck dafür - nur Java akzeptiert ihn nicht!
Code:
"[^\\w\\W&&[^/]]+(?![^\\[]*\\])"
Dieser findet korrekt alle Slashes die nicht in eckigen Klammern sind, wenn ich es auf http://regexpal.com/ teste.
Wenn ich es aber in Java mach ( string.split(regex) ) bekomme ich den Ausgangsstring, was heisst, dass kein match gefunden wurde.
 
Zuletzt bearbeitet:
Was soll am Ende Raus kommen?

  • Text (Zahl;Zahl) oder
  • die ganze Reihe Text Text (Zahl;Zahl)/Text (Zahl;Zahl)/Text (Zahl;Zahl) oder gar nur
  • (Zahl;Zahl)/(Zahl;Zahl)

#Edit: Ist nach jedem ) ein Leerzeichen? Wenn ja kannst du am Schluss (?= / ) machen, dann hast du in deiner MatchCollection z.B Text mit Sonderzeichen ( -3; -2 ) (Wenn vor dem (?= / ) alles an Ort und stelle war ;))
#Edit2: (?![^\\[]*\\]) Ist ein "negative look-ahead", heißt, es darf nicht nach: "[^\\w\\W&&[^/]]" auftreten, sonst gibt es keinen Match
 
Zuletzt bearbeitet:
Zeile 2 mit den Möglichkeiten (-a;b), (a;b), (-a), (-a...b). So hab ich es verstanden.
 
Was ich will :
Code:
String s =  "INIT [km/h] (0) / Text [m/s] (1) / Text (2) / Text (4)";
String[] splitted = s.split("[^\\w\\W&&[^/]]+(?![^\\[]*\\])");
System.out.println("Length: " + splitted.length); // Gibt 1 aus, weil kein Match; Soll 4 sein
Als Ergebnis hätte ich gern folgendes Array:
Code:
["INIT [km/h] (0)", "Text [m/s] (1)", "Text (2)",  "Text (4)"]

Zu den Fragen:
Nein es gibt keine feste Anzahl an Leerzeichen nach der Klammer. Da können auch 50 sein.
Was willst du mit deinem #2 edit sagen? Ich weiss, dass das ein neg. Lookahead ist.
Ich weiss nur net, warum Java den string nicht splitted obwohl die Slashes korrekt im Online RegEx Tester erkannt werden.
 
Weil du keinen String mit einem Regular Expression splitten kannst Das war eine falsche Annahme, da es mir von C# aus nicht bekannt war, dass man in den Split-Befehl ein Regex packen kann)

Okay, es ist möglich, dass \\w etc. Probleme geben könnten, da \\ = \ ergibt. Er sucht also nach \w und nicht nach einem "word character"

#Edit: "/(?![^\\[]*\\])" ist aber nicht der komplette Regex oder? Ist das jetzt diese Riesenzeile vom Anfang + den Teil?
 
Zuletzt bearbeitet:
Doch:
Javadoc String.split(String regex)
Splits this string around matches of the given regular expression.

//edit zu deinem edit :D :
Nein das passt so. Es müssen die Backslashes im String nochmal Escaped werden.
string.split("\\w");
funktioniert.

Siehe hier: Link
If you are using an escaped construct within a string literal, you must preceed the backslash with another backslash for the string to compile. For example:

private final String REGEX = "\\d"; // a single digit

//Edit :

Habs nun hinbekommen. Keine Ahnung warum er den ersten RegEx Ausdruck nicht mochte aber der tuts auch:
Code:
"/(?![^\\[]*\\])"
 
Zuletzt bearbeitet:
Ah jetzt :D... verfluchter * ;), jetzt funktioniert es:
Code:
@"(?<=/|^).*?\(.*?(?=/)"
Bringt die Lösung, wobei natürlich alles gefangen wird, was zwischen den /'s steht bzw Anfang und /.
Das ganze Funktioniert natürlich nur mit einer MatchCollection (bzw. dem Pendant in Java) nicht mit Split, mein Fehler. Ich sollte mal besser lesen lernen

#EDIT: Alles mal wieder aufgeräumt was hier so stand ;)
 
Zuletzt bearbeitet:
Deine version geht bei mir nicht.
Aber das Thema ist für mich eh durch, da es mit meinem ja geht :D

Und doch, das ist die komplette RegEx um die Slashes zu finden (ohne die in eckigen klammern):
/(?![^\\[]*\\])
 
Zurück
Oben