Regular Expression/Quantoren
Quantoren
- Wiederholungsfaktoren (Quantoren)
Quantoren (engl. quantifier, auch Quantifizierer) erlauben es, den vorherigen Ausdruck in verschiedener Vielfachheit in der Zeichenkette zuzulassen.
? | Der voranstehende Ausdruck ist optional, er kann einmal vorkommen, muss es aber nicht, d. h. der Ausdruck kommt null- oder einmal vor. (Dies entspricht {0,1}) |
+ | Der voranstehende Ausdruck muss mindestens einmal vorkommen, darf aber auch mehrfach vorkommen. (Dies entspricht {1,}) |
* | Der voranstehende Ausdruck darf beliebig oft (auch keinmal) vorkommen. (Dies entspricht {0,}) |
>n} | Der voranstehende Ausdruck muss exakt n-mal vorkommen. |
>min,} | Der voranstehende Ausdruck muss mindestens min-mal vorkommen. |
>max} | Der voranstehende Ausdruck muss mindestens min-mal und darf maximal max-mal vorkommen. |
>max} | Der voranstehende Ausdruck darf maximal max-mal vorkommen. |
Funktionsweise
Die Quantoren beziehen sich dabei auf den vorhergehenden regulären Ausdruck, jedoch nicht zwangsläufig auf die durch ihn gefundene Übereinstimmung. * So wird zwar zum Beispiel durch a+ ein „a“ oder auch „aaaa“ vertreten,
- jedoch entspricht [0-9]+ nicht nur sich wiederholenden gleichen Ziffern, sondern auch Folgen gemischter Ziffern, beispielsweise „072345“.
Beispiele
„[ab]+“ * entspricht „a“, „b“, „aa“, „bbaab“ etc.
„[0-9]{2,5}“ * entspricht zwei, drei, vier oder fünf Ziffern in Folgez. B. „42“ oder „54072“, jedoch nicht den Zeichenfolgen „0“, „1.1“ oder „a1a1“.
Gieriges Verhalten von Quantoren
Quantoren sind standardmäßig „gierig“ (engl. greedy) implementiert.
Soll eine Zeichenkette nur aus dem gesuchten Muster bestehen (und es nicht nur enthalten), so muss in den meisten Implementierungen explizit definiert werden, dass das Muster vom Anfang (\A oder ^) bis zum Ende der Zeichenkette (\Z, \z oder $) reichen soll.
- Andernfalls erkennt zum Beispiel [0-9]{2,5} auch bei der Zeichenkette „1234507“ die Teilzeichenkette „12345“.
- Aus dem gleichen Grund würde beispielsweise a* immer einen Treffer ergeben, da jede Zeichenfolge – selbst das leere Wort „“ – mindestens 0-mal das Zeichen „a“ enthält.
- Das heißt, ein regulärer Ausdruck wird zur größtmöglichen Übereinstimmung aufgelöst.
Genügsame Quantoren
Da dieses Verhalten jedoch nicht immer so gewollt ist, lassen sich bei vielen neueren Implementierungen Quantoren als „genügsam“ oder „zurückhaltend“ (engl. non-greedy, reluctant) deklarieren.
- Zum Beispiel wird in Perl hierfür dem Quantor ein Fragezeichen ? nachgestellt.
- Die Implementierung von genügsamen Quantoren ist vergleichsweise aufwändig (erfordert Backtracking), weshalb nicht alle Implementierungen diese unterstützen.
Beispiel (Perl-Syntax)
- Angenommen, es wird der reguläre Ausdruck A.*B auf die Zeichenfolge „ABCDEB“ angewandt, so würde er sie komplett als „ABCDEB“ finden.
- Mit Hilfe des „non-greedy“-Quantors „*?“ matcht der nun modifizierte Ausdruck – also A.*?B – nur die Zeichenkette „AB“, bricht also die Suche nach dem ersten gefundenen „B“ ab.
- Ein gleichwertiger regulärer Ausdruck für Interpreter, die diesen Quantor nicht unterstützen, wäre A[^B]*B.
Die Zeichen ^ und $ matchen im multiline-Modus (wenn der m-Modifier gesetzt wird) auch Zeilenanfänge und -enden.
Possessives Verhalten
Eine Variante des oben beschriebenen gierigen Verhaltens ist das possessive Matching.
- Da hierbei jedoch das Backtracking verhindert wird, werden einmal übereinstimmende Zeichen nicht wieder freigegeben.
- Aufgrund dessen finden sich in der Literatur auch die synonymen Bezeichnungen atomic grouping, independent subexpression oder non-backtracking subpattern.
- Die Syntax für diese Konstrukte variiert bei den verschiedenen Programmiersprachen.
Ursprünglich wurden solche Teilausdrücke (Subpattern) in Perl durch (?>Ausdruck) formuliert.
Daneben existieren seit Perl 5.10 die äquivalenten, in Java bereits üblichen possessiven Quantoren ++, *+, ?+ und {min,max}+.
Angenommen es wird auf die Zeichenfolge „ABCDEB“ der reguläre Ausdruck A.*+B angewandt, so würde er keine Übereinstimmung finden.
- Bei der Abarbeitung des regulären Ausdrucks würde der Teil .*+ bis zum Ende der Zeichenkette übereinstimmen.
- Um jedoch den gesamten Ausdruck zu matchen, müsste ein Zeichen (hier also das „B“) wieder freigegeben werden.
- Der possessive Quantor verbietet dies aufgrund des unterdrückten Backtrackings, weshalb keine erfolgreiche Übereinstimmung gefunden werden kann.