2010-04-07 13 views
6

estoy usando el código de abajo para resaltar algunas palabras clave en un texto:Selecciona el texto, excepto que las etiquetas HTML

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

El texto puede contener algunas etiquetas HTML, por ejemplo <img>, <strong>, etc ..

¿Cómo puedo resaltar el texto "normal", excepto el texto entre las etiquetas html? Porque cuando los usuarios buscan "img", el texto <img> se resaltará y la imagen ya no funcionará.

+0

http://stackoverflow.com/questions/2590862/match-multiple-terms-within-body-tags/2590969#2590969 (sólo una Hace hora!) – bobince

Respuesta

5

Utilice un analizador DOM de algún tipo. Esto no es algo que quieras hacer con regex.

2

De 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); 
} 

Cuando la bandera == $ 1, la función de reemplazo se aplica fuera de HTML. Cuando $ flag == -1, la función de reemplazo se aplica dentro de HTML.

aplicado a su ejemplo, sería dar algo como esto:

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

Enjoy! ;)

+0

Gracias, pero esto es sin un analizador html. Los carteles de arriba dicen que un analizador html sería mejor en este caso (??) – Arjen

+0

Y les digo que las expresiones regulares pueden hacer un muy buen trabajo. Además, no necesitará tener un código html válido: simplemente funcionará. – Savageman

+0

Gracias por su respuesta. El único problema es cuando las palabras clave (que deben ser resaltadas) contienen todos los caracteres alfanuméricos obtengo un error de pérdida de memoria. – Arjen

0

código mejor base de la respuesta de @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); 
Cuestiones relacionadas