Сделать порядок поиска PHP-глобуса нечувствительным

Я учу себя php, поэтому извиняюсь, если это глупый вопрос. У меня есть папка, содержащая много папок, каждая из которых содержит файлы JPG. Я использую приведенный ниже код для поиска файлов, имена которых (и / или имена папок) содержат ВСЕ ключевые слова, отправленные пользователями (в примере ограничено 4 ключевыми словами). Это отлично работает, если ключевые слова отправляются в том же порядке, в каком они появляются в строке папки / файла, но строки с теми же словами в другом порядке не возвращаются. Как я могу это сделать? Большое спасибо!

<?php

$keywords = $_REQUEST['keywords'];

$exploded_keywords = explode(" ", $keywords );

if (isset($exploded_keywords[4])) { $inclusion = '*'.$exploded_keywords[0].'*'.$exploded_keywords[1].'*'.$exploded_keywords[2].'*'.$exploded_keywords[3].'*'.$exploded_keywords[4].'*'; } else { 

if (isset($exploded_keywords[3])) { $inclusion = '*'.$exploded_keywords[0].'*'.$exploded_keywords[1].'*'.$exploded_keywords[2].'*'.$exploded_keywords[3].'*'; } else { 

if (isset($exploded_keywords[2])) { $inclusion = '*'.$exploded_keywords[0].'*'.$exploded_keywords[1].'*'.$exploded_keywords[2].'*'; } else { 

if (isset($exploded_keywords[1])) { $inclusion = '*'.$exploded_keywords[0].'*'.$exploded_keywords[1].'*'; } else { 

if (isset($exploded_keywords[0])) { $inclusion = '*'.$exploded_keywords[0].'*'; }}}}}

$files = glob("$inclusion/*.[jJ][pP][gG]", GLOB_BRACE);

$num = $files[0];

for ($i=0; $i<count($files); $i++) { 
   $num = $files[$i]; 
   $err = 0;
   foreach($exclude as $term) {
      if (stristr($num,$term)) { 
         $err++; }}
   if ( !$err > 0 ) { // display thumbnails... }} ?>

Что-то вроде этого? regex101.com/r/Y9qC25/2 обратите внимание, что я добавил флаги мг для сопоставления нескольких строк.

Lou 12.05.2018 20:53

Первый возвращает соответствие, если были найдены ЛЮБЫЕ ключевые слова. Это будет соответствовать, только если найдены ВСЕ ключевые слова: regex101.com/r/DjzIyf/1

Lou 12.05.2018 21:07
(Не имеет отношения к вашему вопросу) Весь набор операторов if (isset($exploded_keywords... может быть заменен на $inclusion = '*'.str_replace(' ', '*', $keywords).'*'; (т.е. вам даже не нужен explode($keywords)). Если вам нужно ограничить количество ключевых слов до 5, вы можете использовать $exploded_keywords = explode(" ", $keywords); $inclusion = '*'.implode('*', array_slice($exploded_keywords, 0, 5)).'*';
axiac 12.05.2018 21:51

@axiac Разве у него не возникнет такая же проблема с порядком ключевых слов?

Lou 12.05.2018 21:55

@Lou, конечно, он будет. Я предложил упростить существующий код (учитывая, что OP изучает PHP). Я не отвечал на вопрос.

axiac 12.05.2018 21:58

@axiac Да, неплохо, просто хотел убедиться, что что-то не пропустил. Спасибо :)

Lou 12.05.2018 21:59

Спасибо вам обоим. Вы мне очень помогли.

Diego T 13.05.2018 00:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
7
247
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для этого я бы использовал регулярное выражение. См. Последний блок кода для гораздо менее понятной, но простой версии.

<?php
//Its bad practice to use $_REQUEST, you should use $_GET or $_POST if you can..
$keywords = $_REQUEST['keywords'];

//Let's prepare our regex to match our keywords.   
$exploded_keywords = explode(" ", $keywords );
$regex = "/";

//Loop trough your keywords and add them to the regex.
// ?= is a lookahead, if you want to know what it does. http://www.rexegg.com/regex-lookarounds.html
//preg_quote() will escape your keywords so they don't break your regex. Caracters such as ( ) . ? * etc.
foreach($exploded_keywords as $keyword){
    $regex .= "(?=.*".preg_quote($keyword, '/').")";
}

/* 
 * The following block of code has been added just in case it's useful to someone.
 * This will return a match if ANY one keyword is found within the file name. (Case insensitive)
 *
 * $regex = "/.*(";
 * $tmp = '';
 * foreach($exploded_keywords as $keyword) {
 *  $tmp = $tmp."|".preg_quote($keyword, '/');
 * }
 * $regex .= ltrim($tmp, '|') . ").*\.jpg/i";
 */
//match a jpg file. This version is case insensitive for the keywords and the extension.
$regex . = ".*\.jpg/i";
//This would make it case sensitive but for the extension
//$regex . = ".*\.[jJ][pP][gG]/";

//Now let's get the files
$files = glob("*.[jJ][pP][gG]", GLOB_BRACE);

//Let's get our matches
//preg_grep will look in your array values for matches and return the entries as a array. 
//array_values will reindex the keys of the returned array. Otherwise they keep their original keys. 
$matches = array_values(preg_grep($regex, $files));
//Verify your results
print_r($matches);

Укороченная версия:

<?php
$keywords = preg_quote($_REQUEST['keywords']);
$regex = (!empty($keywords)) ? "/(?=.*". str_replace(' ', ')(?=.*', $keywords).")"  . ".*\.[jJ][pP][gG]/" : '/.*/';
$files = glob("*.[jJ][pP][gG]", GLOB_BRACE);
$matches = array_values(preg_grep($regex, $files));
print_r($matches);

Обновлено: добавлен preg_quote () при создании регулярного выражения, поскольку ключевые слова явно поступают из пользовательского ввода.

Другие вопросы по теме