在另一个数组值中查找数组(句子)

时间:2018-10-24 05:03:32

标签: php arrays sorting

我对这种情况感到困惑。我有一个包含300个或更多单词的数组列表,还有另一个包含500个或更多单词的句子列表。所以现在我要提取与单词列表匹配的句子。例如,

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

我想基于$ a个单词提取$ b个句子。我不想使用foreach,因为它将是n个循环。解决这个问题的可行方法是什么?

1 个答案:

答案 0 :(得分:1)

通过调用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
)

Sandbox

如果您确定“单词”将不包含正则表达式的任何特殊内容(主要是标点符号),则可以这样简单地完成操作:

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报价是一项安全功能:

  

preg_quote -引用正则表达式字符    字符串 preg_quote (字符串 $ str [,字符串 $ delimiter = NULL])

     

preg_quote()采用str并将反斜杠放在正则表达式语法中每个字符的前面。如果您有一个需要在某些文本中匹配的运行时字符串,并且该字符串可能包含特殊的正则表达式字符,这将很有用。

     

特殊的正则表达式字符为:。 \ + *吗? [^] $(){} =! <> | :-

     

请注意, / 不是特殊的正则表达式字符。

     

定界符如果指定了可选定界符,也将对其进行转义。这对于转义PCRE功能所需的分隔符很有用。 / 是最常用的定界符。

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

您没有“必须”使用它们,它们确实在“单词”数组上添加了迭代,但是如果您可以使用.?甚至是{{1 }},您可能想使用它。基本上,它逃避了那些事情,因此它们不会被解释为正则表达式的一部分。如果您了解Regex,您可以随时忽略它,并像*这样利用$words = ["shoes?"]shoe匹配它。

正则表达式说明

所使用的模式非常向前:

  • shoes单词边界,空格,标点,字符串的开头和结尾
  • \b捕获组
  • (...)或(|word等)
  • word不区分大小写的标志。

在这种情况下,完整模式如下:

\i

或者用英语,从单词边界开始,匹配列表中的任何单词,结束于单词边界,不区分大小写地匹配

明智的表现,谁知道?如有疑问,请对它们进行基准测试并比较时间差。 /\b(lorem|ipsum|one|three|five)\b/i 的好处是我们正在折叠其中一个数组,然后让PHP和PCRE(Regex引擎)处理实现所需的循环。

享受。