2010-04-07 85 views
6

我使用下面的代碼突出顯示文本的一些關鍵字:突出顯示文本,除了HTML標籤

$message = str_ireplace($words,'<span class="hightlighted_text">'.$words.'</span>',$message); 

文本可能包含某些HTML標記,例如<img><strong>等。

如何突出顯示「正常」文本,但html標記之間的文本除外?因爲當用戶搜索「img」時,<img>文本將突出顯示,並且圖像不再有效。

+0

http://stackoverflow.com/questions/2590862/match-multiple-terms-within-body-tags/2590969#2590969(只是一個小時前!) – bobince 2010-04-07 09:27:26

回答

5

使用某種類型的DOM解析器。這不是你想用正則表達式做的事情。

2

http://forum.phpfrance.com/vos-contributions/remplacement-selectif-hors-dans-balises-html-t199.html

function mon_rplc_callback($capture){ 
    global $arg; 
    return ($arg['flag'] == 1) 
    ? $arg['fct']($arg['from'], $arg['to'], $capture[1]).$capture[2] 
    : $capture[1].$arg['fct']($arg['from'], $arg['to'], $capture[2]); 
} 

function split_tag($from, $to, $txt, $fct, $flag = 1){ 
    global $arg; 
    $arg = compact('from', 'to', 'fct', 'flag'); 
    return preg_replace_callback('#((?:(?!<[/a-z]).)*)([^>]*>|$)#si', "mon_rplc_callback", $txt); 
} 

當$標誌== 1,更換功能外HTML應用。 當$ flag == -1時,替換函數應用於HTML內部。

適用於你的榜樣,它會給這樣的:

echo split_tag($words, '<span class="hightlighted_text">'.$words.'</span>', $message, 'str_ireplace', 1); 

享受! )

+0

謝謝,但是這沒有一個html解析器。以上海報表示,在這種情況下,一個html解析器會更好(??) – Arjen 2010-04-07 15:02:17

+0

而且我告訴你正則表達式可以做得很好。另外你不需要有一個有效的html代碼:它將會正常工作。 – Savageman 2010-04-07 15:12:32

+0

感謝您的回覆。唯一的問題是,當de關鍵字(必須突出顯示)包含所有字母數字字符時,我會遇到內存泄漏錯誤。 – Arjen 2010-04-07 15:57:23

0
基於應答

更好的代碼從@Savageman

$str = '<a href="ba">ba</a>'; 
$highlightWhat = "ba"; 
$str = preg_replace_callback('#((?:(?!<[/a-z]).)*)([^>]*>|$)#si', function($m) use ($highlightWhat) { 
      return preg_replace('~('.$highlightWhat.')~i', '<span style="background:#fff330">$1</span>', $m[1]) . $m[2]; 
     }, 
     $str);