Стрипы PHP не возвращают все позиции
Я возвращаю весь массив, где stripos
функция соответствует этому
$requestedservice = request('service');
$result_array = array_filter($allservicesname, function($item) use ($requestedservice) {
return (stripos($item, $requestedservice) !== false);
});
Это работает только для первого случая, например, если стог сена Walk dance and rock
если игла Walk
это возвращается Walk dance and rock
, но если игла Walk rock
не возвращается Walk dance and rock
, Почему это происходит?
Есть ли способ найти для всех случаев, чтобы он соответствовал стогу сена Walk dance and rock
с иглой Walk rock
?
А также, если игла Walk run
это не должно совпадать Walk dance and rock
это нормальный вариант использования
2 ответа
Похоже, вы сможете добиться желаемой фильтрации с помощью цикла проверок ключевых слов без учета регистра.
Код: ( Демо)
$allservicesname=['dance','Walk rock','Walk dance and rock','Walk']; // array of haystacks
$requestedservice='walk rock'; // string of needles
$result_array=array_filter($allservicesname,function($string)use($requestedservice){
foreach(explode(' ',$requestedservice) as $keyword){
if(stripos($string,$keyword)===false){
return false;
}
}
return true;
});
var_export($result_array);
Выход:
array (
1 => 'Walk rock',
2 => 'Walk dance and rock',
)
Обратите внимание, что оригинальные ключи сохраняются в выходном массиве. Также следует отметить, что ключевые слова могут появляться в любом порядке и сохранять точность.
В качестве альтернативы, если вас не пугает идея регулярных выражений, preg_grep()
может кратко выполнить эту задачу. Это функция, предназначенная для фильтрации массивов с использованием регулярных выражений для каждого элемента.
Код: ( Демо) ( Демо-шаблон Regex)
$allservicesname=['Walk dance and rock walk','dance','walk','rock and walk','sidewalk and rockwall']; // array of haystacks
$requestedservice='walk rock'; // string of needles
$pattern='/(?=.*\Q'.str_replace(' ','\E)(?=.*\Q',$requestedservice).'\E)/i'; // with literal substring matching, no wordboundaries
//$pattern='/(?=.*\b\Q'.str_replace(' ','\E\b)(?=.*\b\Q',$requestedservice).'\E\b)/i'; // with wordboundaries
echo $pattern,"\n";
$result_array=preg_grep($pattern,$allservicesname);
var_export($result_array);
Выход:
/(?=.*\Qwalk\E)(?=.*\Qrock\E)/i
array (
0 => 'Walk dance and rock walk',
3 => 'rock and walk',
4 => 'sidewalk and rockwall',
)
Если вы не хотите элемент [4]
чтобы уточнить, тогда необходимы границы слов - вместо этого используйте второе (закомментированное) описание шаблона.
\Q..\E
гарантирует, что никакие символы со специальным значением в регулярном выражении не могут помешать выполнению. Подстроки внутри них интерпретируются "буквально".
Как уже упоминалось, stripos
возвращает только первое вхождение. После того, как вы превратите строку в массив с explode
Вы можете использовать foreach
цикл с in_array
чтобы выполнить то, что вы ищете.
Вот оно действие:
$all_services = explode(" ", "walk dance and rock");
$requested_services = explode(" ", "walk rock");
$result_array = array();
foreach ($all_services as $service) {
if (in_array($service, $requested_services)) {
$result_array[] = $service;
}
}