Using PHP, I want find all strings including list of words in the same order:
$searchable = array('cat', 'fruit', 'new');
And this strings are match:
'my cat is a Fruit of new';
'cat fruit new';
And this aren't match:
'Cat is my new fruit'
'Cat fruit'
Could you help me?
Simply use a pattern like this:
/cat.*fruit.*new/iu
If you need to automatically generate that pattern, try something like this:
$searchable = array('cat', 'fruit', 'new');
$pattern = '/' . implode('.*',
array_map(function($s) {
return preg_quote($s, '/');
}, $searchable)) . '/iu'; // '/cat.*fruit.*new/iu'
And for fun, here's a non-regex solution:
function matches_sequence($str, $seq) {
for ($i = $c = 0; $i < count($seq); $i++)
{
$c = mb_stripos($str, $seq[$i], $c);
if ($c === false) {
return false;
} else {
$c += strlen($seq[$i]);
}
}
return true;
}
$searchable = array('cat', 'fruit', 'new');
matches_sequence('my cat is a Fruit of new', $searchable); // true
matches_sequence('Cat is my new fruit', $searchable); // false
As a non-regex solution, you can use stripos() .
function find_match($str, $searchable){
$pos_arr = Array();
foreach($searchable as $s){
$pos = stripos($str, $s);
if(
(count($pos_arr) == 0) ||
($pos_arr[count($pos_arr)-1] < $pos) &&
($pos !== false)
){
$pos_arr[] = $pos;
}else{
return false;
}
}
return true;
}
The basic logic is, find the position of the searchable term one by one and store their index in $pos_arr
. If the last entry has an index value greater than the present match, then return false.
Demo -
$searchable = array('cat', 'fruit', 'new');
$strings = Array(
"my cat is a Fruit of new",
'cat fruit new',
'Cat is my new fruit',
'Cat fruit'
);
foreach($strings as $str){
print_r($str);
var_dump(find_match($str, $searchable));
print_r("<br />");
}
/*
OUTPUT-
my cat is a Fruit of new
boolean true
cat fruit new
boolean true
Cat is my new fruit
boolean false
Cat fruit
boolean false
*/