Reputation: 45
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);
print_r($matches);
However, because of the case insensitive modifier, this returns an Array something like the below:
Array
(
[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:
Array
(
[0] => Dog
[1] => Brown
[2] => Fox
)
Thanks in advance.
Upvotes: 2
Views: 392
Reputation: 6534
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.
Anyway...
This is how I would go about this.
<?php
$subject = "The quick brown fox jumps over the lazy dog";
$needles = [
'Dog',
'Clown',
'Brown',
'Fox',
'Dude',
];
// 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.
array_shift($m);
// 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];
}
}
print_r($foundNeedles);
The result being:
Array
(
[0] => Dog
[1] => Brown
[2] => Fox
)
Upvotes: 0
Reputation: 22911
I highly recommend not using regex for this task, as it's not needed. Simply use stripos()
to figure out if an item is in a string.
function findMatches($subject, $items)
{
$matches = array();
foreach ( $items as $item )
{
if ( stripos($subject, $item) !== false )
{
$matches[] = $item;
}
}
return $matches;
}
$subject = "The quick brown fox jumps over the lazy dog";
print_r(findMatches($subject, array('Dog', 'Brown', 'Fx')));
See this fiddle for a demo/performance stats.
You could also do a simply array_filter:
$subject = "The quick brown fox jumps over the lazy dog";
print_r(array_filter(array('Dog', 'Brown', 'Fx'), function($item) use ($subject) {
return stripos($subject, $item) !== false;
}));
Upvotes: 2