diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index dc5e5e62c6..e9ed0b6333 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -26,6 +26,8 @@ class RouteCompiler implements RouteCompilerInterface * @param Route $route A Route instance * * @return CompiledRoute A CompiledRoute instance + * + * @throws \LogicException If a variable is referenced more than once */ public function compile(Route $route) { @@ -34,22 +36,22 @@ class RouteCompiler implements RouteCompilerInterface $tokens = array(); $variables = array(); $pos = 0; - preg_match_all('#.\{([\w\d_]+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + preg_match_all('#.\{(\w+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach ($matches as $match) { if ($text = substr($pattern, $pos, $match[0][1] - $pos)) { $tokens[] = array('text', $text); } - $seps = array($pattern[$pos]); + $pos = $match[0][1] + strlen($match[0][0]); $var = $match[1][0]; if ($req = $route->getRequirement($var)) { $regexp = $req; } else { - if ($pos !== $len) { - $seps[] = $pattern[$pos]; - } - $regexp = sprintf('[^%s]+?', preg_quote(implode('', array_unique($seps)), self::REGEX_DELIMITER)); + // Use the character following the variable as the separator when available + // Use the character preceding the variable otherwise + $separator = $pos !== $len ? $pattern[$pos] : $match[0][0][0]; + $regexp = sprintf('[^%s]+?', preg_quote($separator, self::REGEX_DELIMITER)); } $tokens[] = array('variable', $match[0][0][0], $regexp, $var); diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 7245e7909c..793a04e240 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -96,6 +96,15 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase '', '#^/(?(foo|bar))?$#s', array('bar'), array( array('variable', '/', '(foo|bar)', 'bar'), )), + + array( + 'Route with a variable in last position', + array('/foo-{bar}'), + '/foo', '#^/foo\-(?[^\-]+?)$#s', array('bar'), array( + array('variable', '-', '[^\-]+?', 'bar'), + array('text', '/foo'), + )), + ); }