在PHP中,将字符串与关键字列表进行匹配最有效的方法是什么?

在PHP中,将字符串与关键字列表进行匹配最有效的方法是什么?,php,regex,string,match,Php,Regex,String,Match,我有一个关键字列表,需要检查这些关键字是否出现在字符串中。例如: /* Keywords */ Rock Paper Scissors /* Strings */ "This town rocks!" /* Match */ "Paper is patient" /* Match */ "Hello, world!" /* No match */ 我可以将我的关键字放入数组中,循环遍历它,并在每次迭代中执行preg_match()或substr(),但这似乎有点耗费c

我有一个关键字列表,需要检查这些关键字是否出现在字符串中。例如:

/* Keywords */
Rock
Paper
Scissors

/* Strings */
"This town rocks!"    /* Match */
"Paper is patient"    /* Match */
"Hello, world!"       /* No match */
我可以将我的关键字放入数组中,循环遍历它,并在每次迭代中执行preg_match()或substr(),但这似乎有点耗费cpu。我在regexp方面做了一些工作,但没有取得多少成功

做这件事最有效的方法是什么(在精简代码和低CPU负载方面)


请注意,比较必须不区分大小写。

仅为了查看是否找到任何关键字,您可以将关键字作为数组执行此操作:

if(str_ireplace($keyword_array, '', $string) != $string) {
    //match
} else {
    //no match
}

带有所有可选项的正则表达式将确保字符串被扫描一次,而不是N次扫描N个关键字。PCRE库得到了很好的优化

preg_match('/rock|paper|scissors/i', $string);
如果您的关键字有公共前缀,并且您利用了这一点(基本上是通过构建trie并将其内联),那么它会变得更快:

最后是

preg_grep($regex, $array_of_strings);

这将与字符串数组匹配,并返回匹配的字符串。

如果您事先不知道您的关键字,并且您有多个要搜索的字符串,您可以将关键字内爆为正则表达式,并对字符串进行grep:

$keywords = array ('Rock', 'Paper', 'sciSSors');
$strings  = array (
    "This town rocks!",
    "Hello, world!",
    "Paper is patient",
);

$rc = preg_grep(
    sprintf('/%s/i', implode('|', array_map('preg_quote', $keywords))),
    $strings
);

/**
array(2) {
  [0]=>
  string(16) "This town rocks!"
  [2]=>
  string(16) "Paper is patient"
}
*/

使用正则表达式trie
(?i)(?:石头|布|剪刀)
这个第一级trie是
[psr]
如果你有一堆关键字(比如几千个),使用一个实用程序将它们转换成多级trie。你说“这似乎有点cpu昂贵”,但你试过其中任何一种吗?如果你想知道事情需要多长时间,那么最好的方法就是去尝试。您还可以使用诸如xdebug:str_-ireplace之类的软件包,它将扫描字符串N次以查找N个关键字,并为新字符串分配内存。性能相当差。这不是很可靠:如果你的关键字包含“/”,你就不会得到你想要的。留给读者作为练习。
$keywords = array ('Rock', 'Paper', 'sciSSors');
$strings  = array (
    "This town rocks!",
    "Hello, world!",
    "Paper is patient",
);

$rc = preg_grep(
    sprintf('/%s/i', implode('|', array_map('preg_quote', $keywords))),
    $strings
);

/**
array(2) {
  [0]=>
  string(16) "This town rocks!"
  [2]=>
  string(16) "Paper is patient"
}
*/