Reputation: 205
I have an array with names:
$arr = array('Mark Whalberg', 'Will Ferrell', 'Mel Gibson', 'Tom Cruise');
Then I have a string. This string can contains 1 or more strings. So it can be exploded. Example:
$str = "Will Ferrell";
or
$str = "Ferrell Will";
or
$str = "Ferrell";
What I need is to iterate through $arr and select all the names in it that match my string.
So if the string contains:
$str = "Will Ferrell";
or
$str = "Ferrell";
or
$str = "ferrell Will";
then the second element in the array would be fetched. Regex is the key I presume. What I cannot find is how to make one single expression with exploded parts of the string.
EDIT: Please dont care about iteration and stuff like that. The question is only about the regex to compare the exploded string with an element in the array.
EDIT:
Sorry guy. Here was my attempt:
$arr = array('Mark Whalberg', 'Will Ferrell', 'Mel Gibson', 'Tom Cruise');
$str = "Will Ferrell";
for($i=0;$i<count($arr);$i++){
if (preg_match('/'.$arr[$i].'/i',$str)){
echo $str . ' found';
}
}
This code works but only if the match is exact. If I change to:
$str = "Ferrell Will";
Then I get no results.
EDIT:
Finally I came up with a solution. However, Im afraid its not the best way to do it. Im doing double iteration. Would be nice to hear some comment form you guys:
$arr = array('Mark Whalberg', 'Will Ferrell', 'Mel Gibson', 'Tom Cruise', 'William Ferrell');
$str = "Ferrell Will";
$exploded_str = explode(' ', $str);
$found_array = array();
for($i=0;$i<count($arr);$i++){
$found = 0;
for($x=0;$x<count($exploded_str);$x++){
if (preg_match('/'.$exploded_str[$x].'/i',$arr[$i])){
$found++;
}
}
if($found == count($exploded_str)){
$found_array[count($found_array)] = $arr[$i];
}
}
print_r($found_array);
Upvotes: 0
Views: 51
Reputation: 786349
You can avoid looping through values by using preg_grep
with mapped regex from needle:
$arr = array('Mark Whalberg', 'Will Ferrell', 'Mel Gibson', 'Tom Cruise');
$str = "Ferrell Will";
print_r(preg_grep('/' . join('', array_map(function($v) { return '(?=.*'.$v.')'; },
explode(' ', $str))) .'/', $arr));
Output:
Array
(
[1] => Will Ferrell
)
And this:
$str = "Will Ferrell";
print_r(preg_grep('/' . join('', array_map(function($v) { return '(?=.*'.$v.')'; },
explode(' ', $str))) .'/', $arr));
Output:
Array
(
[1] => Will Ferrell
)
join with array_map
is creating this lookaround regex from search string:
(?=.*Ferrell)(?=.*Will)
which will make sure to find all the words in the haystack in preg_grep
call.
Upvotes: 2
Reputation: 1420
I don't see any use case for this - but I think a possible solution would involve some exploding, strtolowering and array_diffing:
$arr = array('Mark Whalberg', 'Will Ferrell', 'Mel Gibson', 'Tom Cruise');
$str = "Will Ferrell";
$compare = array_map('strtolower', explode(" ", $str));
foreach($arr as $lookup)
{
$lookup_arr = array_map('strtolower', explode(" ", $lookup));
if(count(array_diff($compare, $lookup_arr)) == 0) {
echo $str . ' found';
}
}
Not tested at all.
Upvotes: 0