2011-12-15 63 views
1

長時間的潛伏者,第一次海報 - 請裸露在我身邊,我是一個正則表達式n00b,但是我對項目的某些功能有了很好的想法,並且我盡力實現它,盡我所能,但我需要一點幫助才能達到預期的效果。有問題的頁面是:http://dev.favorcollective.com/guidelines/(只是提供一些背景)如何忽略由特定字符串包裝的正則表達式匹配?

我使用PHP的preg_replace函數要經過特定頁面的內容(巨字符串),我有它搜索術語詞彙表,然後我包裹用一點html來啓用動態詞彙表定義工具提示。

這裏是我當前的代碼:

function annotate($content) 
{ 
    global $glossary_terms; 
    $search = array(); 
    $replace = array(); 
    $count=1; 

    foreach ($glossary_terms as $term): 
     array_push($search,'/\b('.preg_quote($term['term'],'/').')[?=a-zA-Z]*/i'); 
     $id = "annotation-".$count; 
     $replacement = '<a href="'.get_bloginfo('url').'/glossary#'.preg_replace('/\s+/', '', $term['term']).'" class="annotation" rel="'.$id.'">'.$term['term'].'</a><span id="'.$id.'" style="display:none;"><span class="term">'.$term['term'].'</span><span class="definition">'.$term['def'].'</span></span>'; 
     array_push($replace,(string)$replacement); 

     $count++; 

    endforeach; 

    return preg_replace($search, $replace, $content); 
} 

•但是,如果我想忽略的<^h#> </H#>標籤內的比賽是什麼?

•我也有一個特殊的字符串,我不想要一個特定的術語來匹配。例如,我希望「熟練程度」一詞在任何時候與「ACTFL熟練程度指南」中不使用的時候匹配,我將如何着手爲我的正則表達式添加例外情況?這甚至是一個選擇嗎?

•最後,如何將匹配的文本作爲變量返回?目前,當我匹配以's'或'ing'結尾的術語(故意使用)時,我的腳本將打印匹配的術語而不是匹配的原始字符串(即將其替換爲「description」和「description」)。無論如何要這樣做?

謝謝!

+1

歡迎SO!有關使用正則表達式處理HTML的信息,請閱讀[本介紹性文章](http://stackoverflow.com/a/1732454/596781)。 – 2011-12-15 17:46:34

回答

3

不是一個PHP的傢伙(C#),但在這裏。我認爲:

'/\b('.preg_quote($term['term'],'/').')[?=a-zA-Z]*/i'將映射到這個更具可讀性模式:

/\b(ESCAPED_TERM)[?=a-zA-Z]*/i 

所以,儘量排除<^h#>類型的變量,正則表達式是確定只有在你認爲你的數據會簡單,非嵌套案例:< h#> TERM < h#>。如果可以的話,你可以使用負前瞻斷言:

/\b(ESCAPED_TERM)(?!<h\d>)[?=a-zA-Z]*/i 

你可以使用一個lookahead with a lookbehind來處理你的特殊情況:

/\b(ESCAPED_TERM|(?<!ACTFL)Proficiency(?!\sGuidelines))(?!<h\d>)[?=a-zA-Z]*/i 

注:如果你有一大堆的這些特殊情況, PHP可能(應該)有一個「忽略空白」標誌,它可以讓你把每個標記放在換行符上。

0

正則表達式很棒,很棒,很神奇。但一切都有其限度。

這就是爲什麼擁有像PHP這樣的語言來提供額外功能的原因。 :)

你可以去掉非貪婪的正則表達式的頭?

$content = preg_replace('/<h[1-6]>.*?<\/h[1-6]>/sim', "", $content); 

如果非貪婪評估不起作用,那麼假設您的標頭中不會有任何其他HTML?

$content = preg_replace('/<h[1-6]>[^<]*<\/h[1-6]>/im', "", $content); 

此外,你可能想用sprintf簡化您的更換:

/* 
    1 get_bloginfo('url') 
    2 preg_replace('/\s+/', '', $term['term']). 
    3 $id 
    4 $term['term'] 
    5 $term['def'] 
*/ 
$rfmt = '<a href="%1$s/glossary#%2$s" class="annotation" rel="%3$s">%4$s</a><span id="%3$s" style="display:none;"><span class="term">%4$s</span><span class="definition">%5$s</span></span>'; 

... 

$replacement = sprintf($rfmt, get_bloginfo('url'), preg_replace('/\s+/', '', $term['term']), $id, $term['term'], $term['def']); 
相關問題