user1963937
user1963937

Reputation: 205

Regular expression with multiple search strings

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

Answers (2)

anubhava
anubhava

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

mgrueter
mgrueter

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

Related Questions