You probably want to return a matching group based on a previous pattern matches:
$word = '[a-z]+';
$sep = '[, ]+';
$words = $captures("~($word)(?:{$sep})?~");
$of = $captures("~xxx ({$word}(?:{$sep}{$word})*) xxx~");
print_r($words($of($subject)));
Output:
Array
(
[0] => red
[1] => blue
[2] => pink
[3] => purple
)
Whereas $captures
is a function that return a pre-configured preg_match_all
call allowing to process not only a string as subject but anything foreach
can operate on:
$captures = function ($pattern, $group = 1) {
return function ($subject) use ($pattern, $group) {
if (is_string($subject)) {
$subject = (array)$subject;
}
$captures = [];
foreach ($subject as $step) {
preg_match_all($pattern, $step, $matches);
$captures = array_merge($captures, $matches[$group]);
}
return $captures;
};
};
By default and as used in the example above, it returns the first group (1), but this can be configured.
This allows to first match the outer pattern ($of
) and then on each of those matches the inner pattern ($words
). The example in full:
$subject = '/xxx red, blue, pink, purple xxx/';
$captures = function ($pattern, $group = 1) {
return function ($subject) use ($pattern, $group) {
if (is_string($subject)) {
$subject = (array)$subject;
}
$captures = [];
foreach ($subject as $step) {
preg_match_all($pattern, $step, $matches);
$captures = array_merge($captures, $matches[$group]);
}
return $captures;
};
};
$word = '[a-z]+';
$sep = '[, ]+';
$seq = "";
$words = $captures("~($word)(?:{$sep})?~");
$of = $captures("~xxx ({$word}(?:{$sep}{$word})*) xxx~");
print_r($words($of($subject)));
See the live-demo.