В принципе, у меня есть массив ключевых слов и фрагмент текста. Мне интересно, какой был бы лучший способ узнать, присутствует ли в тексте какое-либо из этих ключевых слов, учитывая проблемы с производительностью.
Я думал просто перебирать массив и делать strpos () для каждого ключевого слова, но с более чем десяти тысячами слов в массиве, для PHP требуется немного времени, чтобы сделать это, и поэтому мне было интересно, есть ли более эффективный способ сделать это.
В зависимости от размера строки Вы можете использовать хэш, чтобы сделать его быстрее.
Сначала перебираем текст. Для каждого слова назначьте его массиву:
foreach (preg_split("/\s/", $text) as $word) { $string[$word] = 1; }
Затем повторите проверку ключевых слов в строке $:
foreach ($keywords as $keyword) { if (isset($string[$keyword])) { // $keyword exists in string } }
EDIT Если ваш текст намного меньше ваших ключевых слов, сделайте это в обратном порядке, проверьте ключевые слова для каждого слова в тексте. Это будет быстрее, чем указано выше, если текст довольно короткий.
foreach (preg_split("/\s/", $text) as $word) { if (isset($keywords[$word])) { //might be faster if sizeof($text) < sizeof($keywords) } }
Предполагая, что форматирование и только то, что вам нужно, если есть какие-либо (не те) ключевые слова, вы можете попробовать что-то вроде:
$keywords = array( "dog", "cat" ); // get a valid regex $test = "(\b".implode( "\b)|(\b", $keywords )."\b)"; if( preg_match( $test, "there is a dog chasing a cat down the road" ) ) print "keyword hit";
Исследуя идею eWolf …
foreach($keywords as &$keyword) { $keyword = preg_quote($keyword); } $regex = "/(". implode('|', $keywords) .")/"; return preg_match($regex, $str);
Вам не нужно проверять границы, если вы этого не хотите, но если вы просто окружаете группу ()
символы ()
) с помощью \ b, то она будет соответствовать только данному слову. И вы захотите убедиться, что все элементы массива preg_quoted, для обеспечения безопасности.
Я действительно не знаю, эффективнее ли это, но вы можете попытаться поместить их в регулярное выражение следующим образом: (keyword1 | keyword2 | …) С помощью функции preg_quote вы можете избежать ключевых слов для регулярного выражения. Если вы установите компилируемую опцию, она может быть более эффективной при использовании ее с несколькими строками.
Вы можете выгрузить текст в массив и сделать массив_intersect_key на двух массивах. Я не уверен в производительности этого, хотя …