Regex Regular Grab
php > preg_match("@/m(/[^/]+)+/t/ ?@ ", "/m/part/other-part/t", $m); php > var_dump($m); array(2) { [0]=> string(20) "/m/part/other-part/t" [1]=> string(11) "/other-part" } php > preg_match_all("@/m(/[^/]+)+/t/ ?@ ", "/m/part/other-part/t", $m); php > var_dump($m); array(2) { [0]=> array(1) { [0]=> string(20) "/m/part/other-part/t" } [1]=> array(1) { [0]=> string(11) "/other-part" } } In this example, I would like the capture to match both /part and /other-part , unfortunately with regex /m(/[^/]+)+/t/? doesn't display both as i expect.
This capture should not be associated only with this sample; it should record the number of repetitions of the undefined group of the capture group; e.g. /m/part/other-part/and-another/more/t
UPDATE: Given that this is the expected behavior, my question is how can I achieve this match for mine?
Try it:
preg_match_all("@(?:/m)?/([^/]+)(?:/t) ?@ ", "/m/part/other-part/another-part/t", $m); var_dump($m); He gives:
array(2) { [0]=> array(3) { [0]=> string(7) "/m/part" [1]=> string(11) "/other-part" [2]=> string(15) "/another-part/t" } [1]=> array(3) { [0]=> string(4) "part" [1]=> string(10) "other-part" [2]=> string(12) "another-part" } } // EDIT
IMO the best way to do what you want is to use preg_match () from @stema and explode the result / to get a list of the parts you need.
This is how capture groups work. Duplicate capture groups have only the last match saved after the regex. That is in your "/ other piece" test.
Try this instead
/m((?:/[^/]+)+)/t/? Look here at Regexr , while hover over a match, you can see the contents of the capture group.
Just make your group not exciting by adding ?: At the beginning and place another one around the entire repetition.
In php
preg_match_all("@/m((?:/[^/]+)+)/t/ ?@ ", "/m/part/other-part/t", $m); var_dump($m); Conclusion:
array(2) { [0]=> array(1) { [0]=> string(20) "/m/part/other-part/t" } [1]=> array(1) { [0]=> string(16) "/part/other-part" } } As already stated in the comment, you cannot do this right away because preg_match does not allow you to return the same subgroup matches (for example, you can use Javascript or .Net, see Get duplicate matches with preg_match_all () ). Thus, you can divide the operation into several stages:
- Align the object, remove the part you are interested in.
- Match only the part of interest.
the code:
$subject = '/m/part/other-part/t'; $subpattern = '/[^/]+'; $pattern = sprintf('~/m(?<path>(?:%s)+)/t/?~', $subpattern); $r = preg_match($pattern, $subject, $matches); if (!$r) return; $r = preg_match_all("~$subpattern~", $matches['path'], $matches); var_dump($matches); Conclusion:
array(1) { [0]=> array(2) { [0]=> string(5) "/part" [1]=> string(11) "/other-part" } }