У меня есть новостной сайт, содержащий архив с более чем 1 миллионом новостей. Я создал базу данных определений слов с около 3000 записей, состоящую из пар слов.
То, что я хочу сделать, это добавить определение рядом с каждым появлением этих слов в новостях. Я не могу сделать статическое изменение, так как я могу добавить новое ключевое слово каждый день, поэтому я могу сделать его в реальном времени или кэшироваться.
Вопрос в том, что str_replace
или preg_replace
будут очень медленными для поиска 3 тысяч ключевых слов в тексте и их замены.
Есть ли быстрые альтернативы?
str_replace не будет работать для вас (если вы не хотите, чтобы «perl» в «превосходном» был ключевым словом), вам нужно что-то, что учитывает границы слов (например, preg_replace with \b
). Конечно, вы не можете предварительно создать все 3000 ключевых слов сразу, но один документ вряд ли может содержать их все, поэтому я бы предложил предварительно проиндексировать все документы, например, поддерживая индексную таблицу doc_id-> word_id. При обслуживании определенного документа запрашивайте индекс и заменяйте только те ключевые слова, которые фактически содержат документ (предположительно, не более 100).
С другой стороны, если документы коротки, поддержание индексной таблицы может не стоить проблем. Вы можете просто выполнить предварительную индексацию «на лету», например, с помощью strpos
:
$kw = array(); foreach($all_keywords as $k) if(strpos($text, $k)) $kw[] = $k; // $kw contains only words that actually occur in the text // (and perhaps some more, but that doesn't matter) preg_replace_callback('/\b(' . implode('|', $kw) . ')\b/', 'insert_keyword', $text)
str_replace довольно zippy и, насколько мне известно, самый быстрый, который вы найдете для PHP. Конечно, вы должны хранить кеш; что обойдет проблемы с производительностью.
это всего лишь предложение ускорить процесс, уменьшить ошибки и т. д.