Mein String sieht z. B. so aus:
'X<$!> X<$ERRNO> X<$OS_ERROR>'.
Ich möchte die Texte zwischen <...> extrahieren. Der 1. Fall matcht auf
/^X<(.+?)>/, die nachfolgenden auf
/ X<(.+?)>/. Es können zwischen 0 und 4 Nachfolger sein (meine Daten stammen aus perl/lib/perlvar.pod). Den 1. Nachfolger kann ich mit
/^X<(.+?)> X<(.+?)>/ holen (wenn es denn einen gibt).
Für den allgemeinen Fall baue ich eine Wiederholungsklammer ein:
/^X<(.+?)>(?: X<(.+?)>){0,4}/. Hoppla, jetzt wird nur der
letzte Nachfolger gefunden. greedy?? Ich ersetze
{0,4} durch
* oder
+. Selber Misserfolg. Ich versuche es mit
/^X<(.+?)>(?: X<(.+?)>)?(?: X<(.+?)>)?(?: X<(.+?)>)?(?: X<(.+?)>)?/. Damit erhalte ich endlich alle vorhandenen Nachfolger. Mit
/ X<(.+?)>/g klappts auch, könnte aber auch falsch positive Treffer bringen.
So weit, so gut. Aber innerlich habe ich mich wohl weiter mit dem "greedy" beschäftigt. Nach einiger Zeit kam mir plötzlich die Erkenntnis: Meine "greedy" Regex
hatte richtig gearbeitet. Und sie hatte - ebenfalls richtig -
jeden Nachfolger-Treffer in $2 abgelegt.
Fazit: In Wiederholungsklammern darf keine fangende Klammer vorkommen.
Ich schreibe dies für den Fall, dass wieder jemand in diese Falle tappt.
modedit Editiert von GwenDragon: Titel auf Problem angepasst
Last edited: 2014-10-21 14:04:55 +0200 (CEST)
Gruß
GUIfreund