Reputation: 1189
Consider the following strings
home
administrator
admin
admin/
admin/users/index
and preg_match("/^admin\/?(P<controller>[a-z-]+)?\/?(?P<action>[a-z-]+)?$/i", $input_line, $output_array);
it is working to match the last 3 strings as expected, but also matches 'administrator' returning 'istrator' as the "controller"
How do I make the '/' optional, but any other character not count. I have tried things like [^a-z]\/?
but am at a loss. Is it possible?
the logic is;
1. match admin
2. next character(s) are all optional
2.1 if next character exists, it must be /
live example https://www.phpliveregex.com/p/oaQ
Upvotes: 1
Views: 114
Reputation: 626748
You may use optional non-capturing groups as containers around the named capturing groups where the patterns can be obligatory:
'~^admin(?:\/(?P<controller>[a-z-]+))?(?:\/(?P<action>[a-z-]+))?\/?$~i'
See the regex demo.
Details
^
- start of stringadmin
- the admin
substring(?:\/(?P<controller>[a-z-]+))?
- an optional non-capturing group matching 1 or 0 repetitions of
\/
- a /
char(?P<controller>[a-z-]+)
- Group controller
: 1+ ASCII letters or -
(also, consider using [^\/]+
instead to match any 1+ chars other than /
)(?:\/(?P<action>[a-z-]+))?
- Group action
: 1+ ASCII letters or -
(also, consider using [^\/]+
instead to match any 1+ chars other than /
)\/?
- an optional /
$
- end of string.Upvotes: 1