내 사이트에는 카톨릭 백과 사전이 있습니다. 그것에는 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;
}
이렇게 preg_replace를하면 단어를 두 번 바꾸지 않습니다. strtr을 사용 하겠지만, 단어의 일부가 아닌 완전한 단어임을 보장 할 방법이 없습니다.
이렇게 빨리 만들 수있는 방법이 있습니까? 지금은 꽤 느립니다.
감사합니다. 결과를 좁히기 위해 ** 같은 ** 또는 비슷한 것을 사용해야합니다. 그렇지 않으면 30,000 개 이상의 용어를 모두 반환 할 때 속도가 더 느립니다. – devbanana
은'% whatever %'이어야합니까? '% whatever'만을 사용하여 최적화 할 수 있습니다. –
예, % term %이어야합니다. 그렇지 않으면 용어가 주어진 텍스트의 처음이나 끝에 있어야하므로 작동하지 않습니다. – devbanana