Hallo alle,
ich suche Regex-Unterstützung für folgende Aufgabenstellung, bzw. hätte gerne einen Tipp, ob und wie man sie in eine mehrstufige Prüfung (gerne mit Regexen) aufteilt.
Ein einzeiliger String enthält 1-n Regeln. Leerstellen sind darin dort erlaubt, wo ich es ausdrücklich erlaube. Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist. Ich möchte mich nicht in Monster wie Antlr oder so einarbeiten, die für diese Aufgabe vermutlich die beste Lösung wären...
Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
Eine Source-Referenz ist ein einfacher Name. Er kann aus ASCII-Buchstaben und Ziffern bestehen, darf aber nicht mit einer Ziffer beginnen. Ja, ich weiß, es gibt UNICODE. Hier brauche ich aber ASCII. (?<dataRef>[a-zA-Z][a-zA-Z0-9]*)
Vergleichsoperator ist =, !=, <, >, <=, >= oder LIKE. Die Vergleichsoperatoren können von Leerstellen umgeben sein, LIKE muss mindestens eine Leerstelle vor und hinter sich haben.
Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
Ein einfacher Wert kann eins von drei Dingen sein:
- Eine Integerzahl
- Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
- Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz. ($foo, $bar.name). Eine Datenreferenz kann eins von dreien sein:
- sie ist leer ("$" ist eine zulässige Variablenreferenz)
- ein erweiterter Name, bestehend aus Buchstaben, Ziffern, Minuszeichen und Unterstrich
- Eine Datenreferenz, gefolgt von einem Punkt, gefolgt von einem erweiterten Namen.
Meine Definition erlaubt "$.foo" als Variablenreferenz, das ist korrekt so. Besondere Regeln, wie sich ein Namensteil aus den zulässigen Zeichen zusammensetzt, gebe ich nicht vor.
Eine Werteliste besteht aus einer linken Klammer, einer beliebigen Menge von einfachen Werten, die durch Komma getrennt sind, und einer rechten Klammer. Die Kommas dürfen von Leerstellen umgeben sein.
Rechenoperationen oder String-Operatoren habe ich mir verkniffen. Das wäre eventuell zwar hilfreich, aber dann wird es noch wüster.
Meine bisherigen Versuche sind alle in einem Sumpf von Redundanz abgesoffen, bzw. sind daran gescheitert, bei Kommas und Klammern - vor allem innerhalb von Stringkonstanten - sauber abzugrenzen.
Einige Teilausdrücke, mit denen ich mein Glück versucht habe:
Integerzahl: -?[0-9]×
Stringkonstante: '.?(?<!\)'
Einfacher Name: [a-z][a-z0-9]
Variablenreferenz: ${1,2}[a-z0-9_-](.[a-z0-9_-])
Wie mach ich's am besten?
Rolf
Dosen sind silbern