Стрипы 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;
    }
}
Другие вопросы по тегам