Symfony Routing Requirements – Regex Pattern
22.07.2008Das Routing System von Symfony 1.0 ist ja eigentlich sehr cool. Manchmal bringt es einen aber auch gerne zum Wahnsinn, nämlich immer dann, wenn man versucht mit eigenen Regex-Patterns bestimmte Routen zu erzeugen. Zumindest geht es mir so.
In unserm Fall wurden Länder- und Kontinentnamen in der URL als Parameter übergeben. Diese Namen enthielten nicht nur Zeichen, die dem Pattern \w+ entsprechen, sondern leider auch Zeichen, die in diesem Pattern (nur alphanumerische Zeichen) nicht enthalten sind, z.B. das Plus Zeichen, das zum Enkodieren von Leerzeichen in URLs verwendet werden kann. Die entsprechenden Routen greifen dann nicht mehr, sobald solch ein Parameter in der URL auftaucht.
Nach einer guten Weile Trial and Error und ist dann am Ende folgende Regex herausgekommen: [0-9a-zA-ZüöäÜÄÖ%\+-]+
Da Regular Expressions gerne Fragezeichen in Gesichter Zaubern, das ganze in Worten: Der erste Teil (0-9a-zA-Z) bildet alphanumerische Zeichen ab. Dazu sind noch Umlaute, Prozent, Minus und Plus erlaubt. Die ersten Minuszeichen werden dabei als Range interpretiert (a bis z), während das letzte Minus als eigenständiges Zeichen verstanden wird. Das Plus muss mit einem Backslash escaped werden, da es im Rahmen von Regexpressions eine besondere Bedeutung hat, nämlich die Häufigkeit des Vorkommens festzulegen. Das zweite Pluszeichen hinter den eckigen Klammern hat genau diese Aufgabe und definiert, dass der beschriebene String aus mindestens einem oder mehreren der angegebenen Zeichen bestehen muss.
Eine vollständige Routing-Regel sieht dann z.B. so aus:
discover_country:
url: /entdecken/:continent/:safename/:listtype/:page/*
param: { module: discover, action: index, page: 1, listtype: Uebersicht, marker: Laender }
requirements: { continent: \w+, safename: [0-9a-zA-ZüöäÜÄÖ%\+-]+, listtype: \w+, page: \d+ }
Das gemeine ist, dass “normale” Regex nicht greifen:
^[0-9a-zA-ZüöäÜÄÖ%\+-]+$ funktioniert jedenfalls nicht, obwohl das Pattern laut Regextester eigentlich korrekt sein sollte. Die Zeichen ^ und $, die jeweils Anfang und Ende eines Strings markieren, müssen also in den Symfony-Routingregeln weggelassen werden.
Hoffentlich hilft dieser Tipp einigen Menschen bei der Suche nach der Lösung für ähnliche Probleme.