Chad
Chad

Reputation: 1189

regex to match a specific character but is optional

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

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

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 string
  • admin - 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

Related Questions