I would use a single regex to validate/match the whole route string and extract the controller, action, parameters and type from the returned $matches array. The parameters part, which can have a variable number of parts, is parsed afterward. Here is a tested PHP script wit a commented regex that should be a pretty good starting point:
<?php // test.php Rev:20121105_1900
$route = '/controller/action/param1/param2/param3.html';
$re = '%
# Parse controller, action, params and type from route.
^ # Anchor to start of string.
/ # $controller prefix (required).
(?P<controller> # $controller (required).
[^/\\\\.]+ # Value = one or more non-/\..
) # $controller (required).
(?: # Action is optional.
/ # $action prefix.
(?P<action> # $action.
[^/\\\\.]+ # Value = one or more non-/\..
) # $action.
)? # Action is optional.
(?: # Parameters are optional.
(?P<params> # $params.
(?: # One or more parameters
/ # Params separated by a /.
[^/\\\\.]+ # Value = one or more non-/\..
)+ # One or more parameters
) # $params.
)? # Parameters are optional.
\. # $type prefix (required).
(?P<type> # $type (required).
[^/\\\\.]+ # Value = one or more non-/\..
) # $type (required).
$ # Anchor to end of string.
%x';
if (preg_match($re, $route, $matches)) {
// Valid route string.
printf("OK: \"%s\" is a valid route string.\n", $route);
printf( " controller = \"%s\"\n", $matches['controller']);
printf( " type = \"%s\"\n", $matches['type']);
if ($matches['action']) {
printf( " action = \"%s\"\n", $matches['action']);
} else {
printf( " action = (none)\n");
}
if ($matches['params']) {
printf( " params = \"%s\"\n", $matches['params']);
$params = preg_split('%/%', $matches['params'], -1, PREG_SPLIT_NO_EMPTY);
for ($i = 0; $i < count($params); ++$i) {
printf( " p[%d] = \"%s\"\n", $i+1, $params[$i]);
}
} else {
printf( " params = (none)\n");
}
} else {
// Not a valid route string.
printf("ERROR: \"%s\" is NOT a valid route string.\n", $route);
}
?>
Output:
OK: "/controller/action/param1/param2/param3.html" is a valid route string.
controller = "controller"
type = "html"
action = "action"
params = "/param1/param2/param3"
p[1] = "param1"
p[2] = "param2"
p[3] = "param3"