huberu huberu - 1 year ago 68
PHP Question

preg_match_all to return pattern matches rather than subject matches

I'm trying to return the matches from a string as below:

$subject = "The quick brown fox jumps over the lazy dog";
$pattern = "/(Dog|Brown|Fox)/i";
$pregMatchCount = preg_match_all($pattern, $subject, $matches);

However, because of the case insensitive modifier, this returns an Array something like the below:

[0] => dog
[1] => brown
[2] => fox

The case insensitive modifier is important, as the pattern will be dynamically generated. There are other ways around this, however it would be better (and more efficient) if there was a way to catch the pattern matches in this instance, like below:

[0] => Dog
[1] => Brown
[2] => Fox

Thanks in advance.

Answer Source

I believe the original answer, although it solves the sample problem stated by the OP, doesn't address the primary question formulated in the title.

Imagine someone desperately looking for an answer to this/some problem up, finding this page on Stack Overflow... and the answer wouldn't address the original problem stated in the title but would be an "alternative solution" to the possibly isolated and thus reduced problem.


This is how I would go about this.


$subject = "The quick brown fox jumps over the lazy dog";

$needles = [

// Optional: If you want to search for the needles as they are,
// literally, let's escape possible control characters.
$needles = array_map('preg_quote', $needles);

// Build our regular expression with matching groups which we can then evaluate.
$pattern = sprintf("#(%s)#i", implode(')|(', $needles));

// In this case the result regexp. would be:
// #(Dog)|(Clown)|(Brown)|(Fox)|(Dude)#i

// So let's match it!
$pregMatchCount = preg_match_all($pattern, $subject, $m);

// Get rid of the first item as it represents all matches.

// Go through each of the matched sub-groups...
foreach ($m as $i => $group) {

    // ...and if this sub-group is not empty, we know that the needle
    // with the index of this sub-group is present in the results.
    if (array_filter($group)) {
        $foundNeedles[] = $needles[$i];



The result being:

    [0] => Dog
    [1] => Brown
    [2] => Fox
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download