2012-02-15 32 views
0

我使用我的WordPress下面的代碼安裝:preg_replace_callback錯誤

function add_glossary_links($content) { 
    global $wpdb, $wordlist; 
    if (!$wordlist && !$wordlist = get_option('wordlist')) { 
     mysql_query('SET SESSION group_concat_max_len = 100000'); 
     $wordlist = $wpdb->get_var('SELECT GROUP_CONCAT(DISTINCT post_title SEPARATOR "|") AS list FROM '.$wpdb->posts.' WHERE post_status="publish" AND post_type="glossary" AND post_parent>0'); 
     add_option('wordlist', $wordlist); 
    } 

    $wordlist = str_replace(array(" ", "'", "."), array("\s", "\'", "\."), $wordlist); 
    echo $wordlist; 

    $content = preg_replace_callback(
     '/\b('.$wordlist.')\b/i', 
     create_function(
      '$matches', 
      'return "<a href=\"/glossary/" . strtolower(substr($matches[0],0,1) . "/" . $matches[0]) . "/\">" . $matches[0] . "</a>";' 
     ), 
     $content 
    ); 

    return preg_replace('/(<[^<]+)<a\s.*?>(.*?)<\/a>/si','$1$2', $content); 
} 

add_filter('the_content', 'add_glossary_links'); 

的想法是,我從我的數據庫中的單詞的列表;如果它們存在,我將它們替換爲適當術語表的鏈接。

$wordlist的呼應,因爲這種:http://pastebin.com/6XnWBJwM

是我收到的錯誤是這樣的:

Warning: preg_replace_callback(): Unknown modifier 'c' in /my.website/wp-content/themes/mytheme/functions.php on line 384

384線是該段的最後一行:

$content = preg_replace_callback(
     '/\b('.$wordlist.')\b/i', 
     create_function(
      '$matches', 
      'return "<a href=\"/glossary/" . strtolower(substr($matches[0],0,1) . "/" . $matches[0]) . "/\">" . $matches[0] . "</a>";' 
     ), 
     $content 
    ); 

我認爲正則表達式的格式和wordlist顯示的方式存在問題,但是我不能爲了我的生活而揣測它。

由於提前,

回答

1

您收到此錯誤的原因之一字中有一個/,這被解釋爲結束符。之後的任何內容都會被解釋爲修飾符,並且「c」不能作爲其中之一。

您應該通過preg_quote()運行輸入,但是由於您將查詢中的值連接起來,因此這種方法無法正常工作。

我建議不要使用GROUP_CONCAT,而是將每個單詞放在自己的行上。然後,取出行並用單詞填充一個數組。最後,使用implode("|",array_map("preg_quote",$words,array_fill(0,count($words),"/")))並將其放入您的正則表達式中。

+1

請注意,沒有第二個參數的'preg_quote()'不會轉義'/'。 – alex 2012-02-15 22:49:15

+0

在編輯中修復。謝謝。 – 2012-02-15 22:51:28

+0

我正在使用GROUP_CONCAT,因爲它是爲了速度目的而向我建議的 - 該列表源自數據庫中的1,750行。有沒有其他解決方法,而不改變SQL? – dunc 2012-02-16 00:43:04

1

您應該通過preg_quote()運行$wordlist

$safeWordlist = implode('|', 
        array_map(function($word) { return preg_quote($word, '/'); }, 
        explode('|', $wordlist)) 
         ); 

CodePad

不要推出自己的逃逸方法:)

+0

嗨,亞歷克斯。是的,我打算刪除'str_replace',因爲它只是我試圖解決問題。如果在陣列中使用約1750個條目,您的代碼是否會影響速度? – dunc 2012-02-16 00:44:45

+0

@dunc可能。你也應該注意正則表達式的限制。它僅限於內存65k。 – alex 2012-02-16 00:46:21

+0

任何關於如何解決這個問題的建議?它需要儘可能快。更多信息可從我的OP上獲取WPSE:http://wordpress.stackexchange.com/questions/41667/ – dunc 2012-02-16 14:04:00