2015-06-19 88 views
2

我有一個關鍵字列表,並需要檢查是否有任何一個字符串出現。例如: -在PHP中,將字符串與關鍵字列表進行匹配的最有效方法是什麼?

/* Keywords */ 
Rock 
Paper 
Scissors 

/* Strings */ 
"This town rocks!" /* Match */ 
"Paper is patient" /* Match */ 
"Hello, world!"  /* No match */ 

我可以把我的關鍵字在陣列中,環路通過它,做在每次迭代的preg_match()或SUBSTR(),但似乎位CPU昂貴。我已經用正則表達式混淆了一下,但沒有取得太大的成功。

要做到這一點,最有效的方法(就精益代碼和低CPU負荷而言)是什麼?

請注意,比較必須不區分大小寫。

+1

使用正則表達式''(?i)(?:rock | paper | scissors)'這個第一級的trie是'[psr]'如果你有一堆關鍵字(就像幾千),使用一個工具來轉換它們進入一個多層次的線索。 http://www.regexformat.com – sln

+0

你說「這似乎有點cpu昂貴」,但你有沒有嘗試過其中任何一個?如果你想知道事情需要多長時間,那麼最好的方法就是實際嘗試它們。您也可以使用像xdebug這樣的軟件包:http://xdebug.org/ –

回答

1

只是爲了看看是否有任何關鍵字找到你可以使用關鍵字作爲數組做到這一點:

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

str_ireplace將爲N個關鍵字掃描字符串N次,併爲新字符串分配內存。非常糟糕的性能。 – Kornel

2

所有替代regex將確保字符串被掃描一次,而不是N倍N個關鍵詞。 PCRE庫非常優化。

preg_match('/rock|paper|scissors/i', $string); 

它變得更快,如果您的關鍵字有共同的前綴,你利用這一點(主要是通過建立一個線索和內聯它):

preg_match('/rock|paper|sci(?:ssors|ence)/i', $string); 

最後還有

preg_grep($regex, $array_of_strings); 

這將匹配一系列字符串並返回匹配的字符串。

0

如果你不知道你的關鍵字提前,你必須要通過搜索多個字符串,就可以爆你的關鍵字,正則表達式和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" 
} 
*/ 

See it here.

+0

這不是非常防彈的:如果你的關鍵字包含「/」,你就不會得到你所期望的。留給讀者閱讀。 – bishop

相關問題