@@ -140,14 +140,18 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
140140foreach ($ tokensas $ token ) {
141141if ('variable ' ===$ token [0 ]) {
142142if (!$ optional || !array_key_exists ($ token [3 ],$ defaults ) ||null !==$ mergedParams [$ token [3 ]] && (string )$ mergedParams [$ token [3 ]] !== (string )$ defaults [$ token [3 ]]) {
143+ $ variablePattern =$ token [2 ];
144+ if ($ this ->hasLookAround ($ token [2 ])) {
145+ $ variablePattern =$ this ->removeLookAround ($ token [2 ]);
146+ }
143147// check requirement
144- if (null !==$ this ->strictRequirements && !preg_match ('#^ ' .$ token [ 2 ] .'$# ' .(empty ($ token [4 ]) ?'' :'u ' ),$ mergedParams [$ token [3 ]])) {
148+ if (null !==$ this ->strictRequirements && !preg_match ('#^ ' .$ variablePattern .'$# ' .(empty ($ token [4 ]) ?'' :'u ' ),$ mergedParams [$ token [3 ]])) {
145149if ($ this ->strictRequirements ) {
146- throw new InvalidParameterException (strtr ($ message ,array ('{parameter} ' =>$ token [3 ],'{route} ' =>$ name ,'{expected} ' =>$ token [ 2 ] ,'{given} ' =>$ mergedParams [$ token [3 ]])));
150+ throw new InvalidParameterException (strtr ($ message ,array ('{parameter} ' =>$ token [3 ],'{route} ' =>$ name ,'{expected} ' =>$ variablePattern ,'{given} ' =>$ mergedParams [$ token [3 ]])));
147151 }
148152
149153if ($ this ->logger ) {
150- $ this ->logger ->error ($ message ,array ('parameter ' =>$ token [3 ],'route ' =>$ name ,'expected ' =>$ token [ 2 ] ,'given ' =>$ mergedParams [$ token [3 ]]));
154+ $ this ->logger ->error ($ message ,array ('parameter ' =>$ token [3 ],'route ' =>$ name ,'expected ' =>$ variablePattern ,'given ' =>$ mergedParams [$ token [3 ]]));
151155 }
152156
153157return ;
@@ -318,4 +322,18 @@ public static function getRelativePath($basePath, $targetPath)
318322 ||false !== ($ colonPos =strpos ($ path ,': ' )) && ($ colonPos < ($ slashPos =strpos ($ path ,'/ ' )) ||false ===$ slashPos )
319323 ?"./ $ path " :$ path ;
320324 }
325+
326+ private function hasLookAround ($ path )
327+ {
328+ if (false ===$ i =strpos ($ path ,'(? ' )) {
329+ return false ;
330+ }
331+
332+ return false !==strpos ($ path ,'(?= ' ,$ i ) ||false !==strpos ($ path ,'(?<= ' ,$ i ) ||false !==strpos ($ path ,'(?! ' ,$ i ) ||false !==strpos ($ path ,'(?<! ' ,$ i );
333+ }
334+
335+ private function removeLookAround ($ path )
336+ {
337+ return preg_replace ('/\(\?(?:=|<=|!|<!)((?:[^() \\\\]+| \\\\.|\((?1)\))*)\)/ ' ,'' ,$ path );
338+ }
321339}