This code outputs the $captured
array, but $captured[1]
contains bar/this
rather than my expected bar
. What's missing in my regex to stop from returning more than bar
?
<?php
$pattern = '/foo/:any/';
$subject = '/foo/bar/this/that';
$pattern = str_replace(':any', '(.+)', $pattern);
$pattern = str_replace(':num', '([0-9]+)', $pattern);
$pattern = str_replace(':alpha', '([A-Za-z]+)', $pattern);
echo '<pre>';
$pattern = '#^' . $pattern . '#';
preg_match($pattern, $subject, $captured);
print_r($captured);
echo '</pre>';
The dot is greedy and matches as many characters as possible. Either make it lazy:
or keep it from matching slashes:
Use a non-greedy modifier to make the
+
match as few characters as possible instead of as many as possible:You probably also want to add delimiters round your regular expression and anchor it to the start of the string:
Your code is rather confusing and misleading and if run it, it outputs a warning:
What I think is wrong is:
because you need to escape a forward slash in regexp.
After this is fixed the script returns:
Which is an expected result. As you match
foo/
and everything afterwards with(.*)
. If you want to match anything until the next forward slash you have some possibilities: