Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
[1] ⟨String⟩ ::= ⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
[2] ⟨Regel⟩ ::= ⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
[3] ⟨SourceReferenz⟩ ::= [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.
~~~
[4] ⟨Vergleichsoperator⟩ ::= \s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*
~~~
Hier ließe sich auch zu `\s*(!?=|[<>]=?|\sLIKE\s)\s*` zusammenfassen, aber das macht den Ausdruck nicht besser lesbar.
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
[5] ⟨Vergleichswert⟩ ::= (⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
[6] ⟨einfacherWert⟩ ::= (⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
[7] ⟨Integerzahl⟩ ::= [+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
[8] ⟨Stringkonstante⟩ ::= '([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
[9] ⟨Variablenreferenz⟩ ::= $$?⟨Datenreferenz⟩
~~~
> 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.
~~~
[10] ⟨erweiterterName⟩ ::= [a-zA-Z0-9_-]+
[11] ⟨leerOderErweiterterName⟩ ::= [a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
[12] ⟨Datenreferenz⟩ ::= ((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
[13] ⟨Werteliste⟩ ::= \(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
[10] und [11] in [12] eingesetzt ergibt:
~~~
[14] ⟨Datenreferenz⟩ = (([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[14] in [9]:
~~~
[15] ⟨Variablenreferenz⟩ = $$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[7], [8], [15] in [6]:
~~~
[16] ⟨einfacherWert⟩ = ([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
~~~
[16] in [13]:
~~~
[17] ⟨Werteliste⟩ = \(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
~~~
[16], [17] in [5]:
~~~
[18] ⟨Vergleichswert⟩ = (([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[3], [4], [18] in [2]:
~~~
[19] ⟨Regel⟩ = [a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[19] in [1]:
~~~
[20] ⟨String⟩ = [a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen, wäre `(?:` statt `(` zu schreiben – außer natürlich bei `\(`.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)
Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
[1] ⟨String⟩::⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
[2] ⟨Regel⟩::⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
[3] ⟨SourceReferenz⟩::[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.
~~~
[4] ⟨Vergleichsoperator⟩::\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*
~~~
Hier ließe sich auch zu `\s*(!?=|[<>]=?|\sLIKE\s)\s*` zusammenfassen, aber das macht den Ausdruck nicht besser lesbar.
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
[5] ⟨Vergleichswert⟩::(⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
[6] ⟨einfacherWert⟩::(⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
[7] ⟨Integerzahl⟩::[+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
[8] ⟨Stringkonstante⟩::'([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
[9] ⟨Variablenreferenz⟩::$$?⟨Datenreferenz⟩
~~~
> 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.
~~~
[10] ⟨erweiterterName⟩::[a-zA-Z0-9_-]+
[11] ⟨leerOderErweiterterName⟩::[a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
[12] ⟨Datenreferenz⟩::((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
[13] ⟨Werteliste⟩::\(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
[10] und [11] in [12] eingesetzt ergibt:
~~~
[14] ⟨Datenreferenz⟩::(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[14] in [9]:
~~~
[15] ⟨Variablenreferenz⟩::$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[7], [8], [15] in [6]:
~~~
[16] ⟨einfacherWert⟩::([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
~~~
[16] in [13]:
~~~
[17] ⟨Werteliste⟩::\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
~~~
[16], [17] in [5]:
~~~
[18] ⟨Vergleichswert⟩::(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[3], [4], [18] in [2]:
~~~
[19] ⟨Regel⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[19] in [1]:
~~~
[20] ⟨String⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen, wäre `(?:` statt `(` zu schreiben – außer natürlich bei `\(`.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)
Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
[1] ⟨String⟩::⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
[2] ⟨Regel⟩::⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
[3] ⟨SourceReferenz⟩::[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.
~~~
[4] ⟨Vergleichsoperator⟩::\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*
~~~
Hier ließe sich auch zu `\s*(!?=|[<>]=?|\sLIKE\s)\s*` zusammenfassen, aber das macht den Ausdruck nicht besser lesbar.
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
[5] ⟨Vergleichswert⟩::(⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
[6] ⟨einfacherWert⟩::(⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
[7] ⟨Integerzahl⟩::[+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
[8] ⟨Stringkonstante⟩::'([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
[9] ⟨Variablenreferenz⟩::$$?⟨Datenreferenz⟩
~~~
> 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.
~~~
[10] ⟨erweiterterName⟩::[a-zA-Z0-9_-]+
[11] ⟨leerOderErweiterterName⟩::[a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
[12] ⟨Datenreferenz⟩::((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
[13] ⟨Werteliste⟩::\(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
[10] und [11] in [12] eingesetzt ergibt:
~~~
[14] ⟨Datenreferenz⟩::(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[14] in [9]:
~~~
[15] ⟨Variablenreferenz⟩::$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[7], [8], [15] in [6]:
~~~
[16] ⟨einfacherWert⟩::([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
~~~
[16] in [13]:
~~~
[17] ⟨Werteliste⟩::\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
~~~
[16], [17] in [5]:
~~~
[18] ⟨Vergleichswert⟩::(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[3], [4], [18] in [2]:
~~~
[19] ⟨Regel⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[19] in [1]:
~~~
[20] ⟨String⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen, wäre `(?:` statt `(` zu schreiben.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)
Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
[1] ⟨String⟩::⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
[2] ⟨Regel⟩::⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
[3] ⟨SourceReferenz⟩::[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.
~~~
[4] ⟨Vergleichsoperator⟩::\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*
~~~
Hier ließe sich auch zu `\s*(!?=|[<>]=?|\sLIKE\s)\s*` zusammenfassen, aber das macht den Ausdruck nicht besser lesbar.
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
[5] ⟨Vergleichswert⟩::(⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
[6] ⟨einfacherWert⟩::(⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
[7] ⟨Integerzahl⟩::[+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
[8] ⟨Stringkonstante⟩::'([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
[9] ⟨Variablenreferenz⟩::$$?⟨Datenreferenz⟩
~~~
> 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.
~~~
[10] ⟨erweiterterName⟩::[a-zA-Z0-9_-]+
[11] ⟨leerOderErweiterterName⟩::[a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
[12] ⟨Datenreferenz⟩::((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
[13] ⟨Werteliste⟩::\(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
[10] und [11] in [12] eingesetzt ergibt:
~~~
[14] ⟨Datenreferenz⟩::(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[14] in [9]:
~~~
[15] ⟨Variablenreferenz⟩::$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[7], [8], [15] in [6]:
~~~
[16] ⟨einfacherWert⟩::([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
~~~
[16] in [13]:
~~~
[17] ⟨Werteliste⟩::\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
~~~
[16], [17] in [5]:
~~~
[18] ⟨Vergleichswert⟩::(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[3], [4], [18] in [2]:
~~~
[19] ⟨Regel⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[19] in [1]:
~~~
[20] ⟨String⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen wäre `(?:` statt `(` zu schreiben.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)
Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
[1] ⟨String⟩::⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
[2] ⟨Regel⟩::⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
[3] ⟨SourceReferenz⟩::[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.
~~~
[4] ⟨Vergleichsoperator⟩::\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*
~~~
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
[5] ⟨Vergleichswert⟩::(⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
[6] ⟨einfacherWert⟩::(⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
[7] ⟨Integerzahl⟩::[+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
[8] ⟨Stringkonstante⟩::'([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
[9] ⟨Variablenreferenz⟩::$$?⟨Datenreferenz⟩
~~~
> 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.
~~~
[10] ⟨erweiterterName⟩::[a-zA-Z0-9_-]+
[11] ⟨leerOderErweiterterName⟩::[a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
[12] ⟨Datenreferenz⟩::((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
[13] ⟨Werteliste⟩::\(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
[10] und [11] in [12] eingesetzt ergibt:
~~~
[14] ⟨Datenreferenz⟩::(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[14] in [9]:
~~~
[15] ⟨Variablenreferenz⟩::$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[7], [8], [15] in [6]:
~~~
[16] ⟨einfacherWert⟩::([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
~~~
[16] in [13]:
~~~
[17] ⟨Werteliste⟩::\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
~~~
[16], [17] in [5]:
~~~
[18] ⟨Vergleichswert⟩::(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[3], [4], [18] in [2]:
~~~
[19] ⟨Regel⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[19] in [1]:
~~~
[20] ⟨String⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=|\sLIKE\s)\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen wäre `(?:` statt `(` zu schreiben.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)
Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
[1] ⟨String⟩::⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
[2] ⟨Regel⟩::⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
[3] ⟨SourceReferenz⟩::[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.
~~~
[4] ⟨Vergleichsoperator⟩::\s*(=|!=|<|>|<=|>=| LIKE )\s*
~~~
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
[5] ⟨Vergleichswert⟩::(⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
[6] ⟨einfacherWert⟩::(⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
[7] ⟨Integerzahl⟩::[+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
[8] ⟨Stringkonstante⟩::'([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
[9] ⟨Variablenreferenz⟩::$$?⟨Datenreferenz⟩
~~~
> 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.
~~~
[10] ⟨erweiterterName⟩::[a-zA-Z0-9_-]+
[11] ⟨leerOderErweiterterName⟩::[a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
[12] ⟨Datenreferenz⟩::((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
[13] ⟨Werteliste⟩::\(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
[10] und [11] in [12] eingesetzt ergibt:
~~~
[14] ⟨Datenreferenz⟩::(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[14] in [9]:
~~~
[15] ⟨Variablenreferenz⟩::$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
~~~
[7], [8], [15] in [6]:
~~~
[16] ⟨einfacherWert⟩::([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
~~~
[16] in [13]:
~~~
[17] ⟨Werteliste⟩::\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
~~~
[16], [17] in [5]:
~~~
[18] ⟨Vergleichswert⟩::(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[3], [4], [18] in [2]:
~~~
[19] ⟨Regel⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=| LIKE )\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
~~~
[19] in [1]:
~~~
[20] ⟨String⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=| LIKE )\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=| LIKE )\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen wäre `(?:` statt `(` zu schreiben.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)
Suche eine Regex
bearbeitet von
@@Rolf b
> Ich möchte diesen String parsen und bei Syntaxfehlern halbwegs exakt angeben können, wo der Fehler ist.
Ich bin mir nicht sicher, ob reguläre Ausdrücke hierfür das geeignete Werkzeug sind.
> Ein einzeiliger String enthält 1-n Regeln. … Regeln sind durch Komma getrennt. Die Kommas dürfen von Leerstellen umgeben sein.
~~~
⟨String⟩::⟨Regel⟩(\s*,\s*⟨Regel⟩)*
~~~
> Eine Regel besteht aus einer Source-Referenz, gefolgt von einem Vergleichsoperator, gefolgt von einem Vergleichswert.
~~~
⟨Regel⟩::⟨SourceReferenz⟩⟨Vergleichsoperator⟩⟨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]*)
~~~
⟨SourceReferenz⟩::[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.
~~~
⟨Vergleichsoperator⟩::\s*(=|!=|<|>|<=|>=| LIKE )\s*
~~~
> Ein Vergleichswert ist ein einfacher Wert oder eine Werteliste.
~~~
⟨Vergleichswert⟩::(⟨einfacherWert⟩|⟨Werteliste⟩)
~~~
> Ein einfacher Wert kann eins von drei Dingen sein:
~~~
⟨einfacherWert⟩::(⟨Integerzahl⟩|⟨Stringkonstante⟩|⟨Variablenreferenz⟩)
~~~
> - Eine Integerzahl
~~~
⟨Integerzahl⟩::[+-]?[0-9]+
~~~
Plus ist erlaubt? Führende Nullen sind erlaubt?
> - Eine Stringkonstante, in Hochkomma eingeschlossen. Hochkomma innnerhalb des Strings werden durch ein \ escaped. Innerhalb des Strings ist alles erlaubt (außer Zeilenumbrüchen...).
~~~
⟨Stringkonstante⟩::'([^']|\\')*'
~~~
> - Eine Variablenreferenz. Das ist ein oder zwei $, gefolgt von einer Datenreferenz.
~~~
⟨Variablenreferenz⟩::$$?⟨Datenreferenz⟩
~~~
> 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.
~~~
⟨erweiterterName⟩::[a-zA-Z0-9_-]+
⟨leerOderErweiterterName⟩::[a-zA-Z0-9_-]*
~~~
Ein erweiterter Name muss nicht mit einem Buchstaben beginnen?
~~~
⟨Datenreferenz⟩::((⟨leerOderErweiterterName⟩\.)*⟨erweiterterName⟩)?
~~~
> 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.
~~~
⟨Werteliste⟩::\(⟨einfacherWert⟩(\s*,\s*⟨einfacherWert⟩)*\)
~~~
Das musst du jetzt nur noch™ alles zusammensetzen:
~~~
⟨Datenreferenz⟩::(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
⟨Variablenreferenz⟩::$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?
⟨einfacherWert⟩::([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)
⟨Werteliste⟩::\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)
⟨Vergleichswert⟩::(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
⟨Regel⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=| LIKE )\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))
⟨String⟩::[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=| LIKE )\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\))(\s*,\s*[a-zA-Z][a-zA-Z0-9]*\s*(=|!=|<|>|<=|>=| LIKE )\s*(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)|\(([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?)(\s*,\s*([+-]?[0-9]+|'([^']|\\')*'|$$?(([a-zA-Z0-9_-]*\.)*[a-zA-Z0-9_-]+)?))*\)))*
~~~
Bei konkreten Implementationen müssen ggfs. Zeichen escapet werden (Johnny 5 sprach `$` an) und wenn Teile nicht gemerkt werden sollen wäre `(?:` statt `(` zu schreiben.
LLAP 🖖
--
“When UX doesn’t consider *all* users, shouldn’t it be known as ‘*Some* User Experience’ or... SUX? #a11y” —[Billy Gregory](https://twitter.com/thebillygregory/status/552466012713783297)