私のサイトには、カトリック百科事典があります。11,000以上の記事があります。
私のサイトの記事の語句をカトリック百科事典の関連項目へのリンクに置き換えることに興味があります。だから、誰かが言うなら:
聖ペテロは最初の教皇でした。
聖ペテロを聖ペテロに関する記事へのリンクに置き換え、教皇を教皇に関する記事へのリンクに置き換える必要があります。
動作していますが、非常に遅いです。30,000 以上の可能な置換があるため、最適化することが重要です。ここからどこへ行けばいいのかわかりません。
これが私の既存のコードです。Drupal を使用していることに注意してください。また、単語を [cathenlink] タグに置き換え、そのタグをコードの後半で実際の HTML リンクに置き換えます。
function ce_execute_filter($text)
{
// If text is empty, return as-is
if (!$text) {
return $text;
}
// Split by paragraph
$lines = preg_split('/\n+/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
// Contains the parsed and linked text
$linked_text = '';
foreach ($lines as $line)
{
// If this fragment is only one or more newline characters,
// Add it to $linked_text and continue without parsing
if (preg_match('/^\n+$/', $line)) {
$linked_text .= $line;
continue;
}
// Select any terms that might be in this line
// Ordered by descending length of term,
// so that the longest terms get replaced first
$result = db_query('SELECT title, term FROM {catholic_encyclopedia_terms} ' .
"WHERE :text LIKE CONCAT('%', CONCAT(term, '%')) " .
'GROUP BY term ' .
'ORDER BY char_length(term) DESC',
array(
':text' => $line
))
->fetchAll();
// Array with lowercase term as key, title of entry as value
$terms = array();
// Array of the terms only in descending order of length
$ordered_terms = array();
foreach ($result as $r)
{
$terms[strtolower($r->term)] = $r->title;
$ordered_terms[] = preg_quote($r->term);
}
// If no terms were returned, add the line and continue without parsing.
if (empty($ordered_terms)) {
$linked_text .= $line;
continue;
}
// Do the replace
// Get the regexp by joining $ordered_terms with |
$line = preg_replace_callback('/\b('.
implode('|', $ordered_terms) .
')\b/i', function ($matches) use($terms)
{
if ($matches[1]) {
return "[cathenlink=" .
$terms[strtolower($matches[1])] . "]" .
$matches[1] . "[/cathenlink]";
}
},
$line);
$linked_text .= $line;
}
return $linked_text;
}
単語を 2 回置き換えないように、このように preg_replace を実行しています。私は strtr を使用しますが、単語の一部ではなく完全な単語であることを確認する方法はありません。
これを速くする方法はありますか?現在、かなり遅いです。