Найти массив в другом значении массива (предложение) - PullRequest
0 голосов
/ 24 октября 2018

Я запутался в ситуации.У меня есть массив списков слов, таких как 300 или более, и у меня есть другой список массивов предложений, таких как 500 или более.Итак, теперь я хочу извлечь предложения, которые соответствуют списку слов.Например,

$a = ['lorem', 'ipsum', 'one', 'three', 'five'];
$b = [
   'lorem ipsum dolor',
   'one word',
   'three horse',
   'ten dolor'
];

Я хочу извлечь предложения $ b на основе слов $ a.Я не хочу использовать foreach, потому что это будет цикл.Каков возможный способ решить эту проблему.

1 Ответ

0 голосов
/ 24 октября 2018

Используя магию preg_grep и регулярные выражения.

$a = ['lorem', 'ipsum', 'one', 'three', 'five'];

$pattern = '/\b('.implode('|',array_map(function($w){
      return preg_quote($w,'/'); //escape the delimiter too
 },$a)).')\b/i';

$b = [
   'lorem ipsum dolor',
   'one word',
   'three horse',
   'ten dolor'
];

print_r(preg_grep($pattern, $b));

Вывод:

Array
(
    [0] => lorem ipsum dolor
    [1] => one word
    [2] => three horse
)

Песочница

Если выВы уверены, что «слова» не будут содержать ничего особенного для Regex (в основном пунктуация), вы можете сделать это так просто:

function matchWordsInSentances($words, array $sentances){
   if(!is_array($words))$words = [$words];
   return preg_grep('/\b('.implode('|',$words).')\b/i', $sentances);
}

preg_grep - вернуть записи массивакоторые соответствуют шаблону

массив preg_grep (строка $ pattern , массив $ input [, int $ flags =0])

Возвращает массив, состоящий из элементов входного массива, соответствующих данному шаблону.

http://php.net/manual/en/function.preg-grep.php

Карта массивов + предварительная кавычка - это функция безопасности, для вашего справочника:

preg_quote - Цитировать символы регулярного выражения строка preg_quote (строка $ str [, строка $ delimiter = NULL])

preg_quote () принимает str и ставит обратную косую черту перед каждым символом, который является частью синтаксиса регулярного выражения.Это полезно, если у вас есть строка времени выполнения, которую необходимо сопоставить в некотором тексте, и строка может содержать специальные символы регулярного выражения.

Специальные символы регулярного выражения: .\ + *?[^] $ () {} =!<> |: -

Обратите внимание, что / не является специальным символом регулярного выражения.

delimiter Если указан дополнительный разделитель, он будеттакже сбежать.Это полезно для экранирования разделителя, который требуется для функций PCRE. / является наиболее часто используемым разделителем.

http://php.net/manual/en/function.preg-quote.php

Вам не нужно их использовать, и они добавляют итерациюнад массивом «слов», но если вы можете иметь такие вещи, как . или ? или даже *, вы можете использовать его.По сути, он избегает этих вещей, поэтому они не интерпретируются как часть регулярного выражения.Если вы знакомы с Regex, вы всегда можете опустить это и воспользоваться его преимуществами, такими как $words = ["shoes?"], что будет соответствовать shoe и shoes.

Объяснение Regex

Используемая схема довольно прямолинейна:

  • \b граница слова, пробелы, пунктуация, начало и конец строки
  • (...) группа захвата
  • | или (word ИЛИ word и т. Д.)
  • \i флаг без учета регистра.

В этом случае полный шаблон выглядит следующим образом:

 /\b(lorem|ipsum|one|three|five)\b/i

Или на английском языке, начинаются с границы слова, совпадают с любым словом в списке, заканчиваются на границе конца слова, без учета регистра.

Производительность, кто знает?Если есть сомнения, сравните их оба и сравните разницу во времени.Хорошая вещь в preg_quote заключается в том, что мы сворачиваем один из массивов, а затем позволяем PHP и PCRE (движку Regex) обрабатывать необходимые циклы.

Наслаждаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...