2009-07-01 21 views
8

¿Hay alguna manera más fácil que esto de quitar HTML de una cadena usando Perl?¿Cómo puedo pegar HTML en una cadena usando Perl?

$Error_Msg =~ s|<b>||ig; 
$Error_Msg =~ s|</b>||ig; 
$Error_Msg =~ s|<h1>||ig; 
$Error_Msg =~ s|</h1>||ig; 
$Error_Msg =~ s|<br>||ig; 

Apreciaría una expresión regular adelgazada, p. Ej. algo como esto:

$Error_Msg =~ s|</?[b|h1|br]>||ig; 

¿Existe una función de Perl existente que elimina cualquier/todo el HTML de una cadena, a pesar de que sólo necesito negritas, encabezados H1 y ancho despojado?

Respuesta

18

Suponiendo que el código es HTML válido (sin perdida < o> operadores)

Si necesita eliminar sólo negritas, de H1 y de ancho

$htmlCode =~ s#</?(?:b|h1|br)\b.*?>##g 

Y es posible que desee considerar la HTML::Strip módulo

+5

No diría que podría, diría que debería. Intentar desinfectar HTML con expresiones regulares es absurdo en este día y edad. Utilice uno de los numerosos módulos de desinfección de HTML del CPAN, preferiblemente algo diseñado para evitar vulnerabilidades de XSS y no escrito por Daniel Muey. –

+2

Cuidado con HTML :: Strip no admite correctamente cadenas codificadas en UTF-8.Consulte aquí para obtener una solución alternativa https://gist.github.com/910818 – nick

14

De perlfaq9: How do I remove HTML from a string?


La forma más correcta (aunque no la más rápida) es usar HTML :: Parser desde CPAN. Otra forma, en su mayoría correcta, es utilizar HTML :: FormatText, que no solo elimina HTML sino que también intenta hacer un pequeño formateo simple del texto sin formato resultante.

Mucha gente intenta un enfoque de expresión regular simple, como s/<. *?> // g, pero eso falla en muchos casos porque las etiquetas pueden continuar sobre saltos de línea, pueden contener corchetes angulares entrecomillados, o comentario HTML puede estar presente. Además, la gente se olvida de convertir entidades, como <, por ejemplo.

Aquí es uno de los enfoques "ingenuo", que funciona para la mayoría de los archivos:

#!/usr/bin/perl -p0777 
s/<(?:[^>'"]*|(['"]).*?\1)*>//gs 

Si desea una solución más completa, ver el programa striphtml de 3 etapas en http://www.cpan.org/authors/id/T/TO/TOMC/scripts/striphtml.gz.

Éstos son algunos casos difíciles que usted debe considerar cuando se escoge una solución:

<IMG SRC = "foo.gif" ALT = "A > B"> 

<IMG SRC = "foo.gif" 
ALT = "A > B"> 

<!-- <A comment> --> 

<script>if (a<b && a>c)</script> 

<# Just data #> 

<![INCLUDE CDATA [ >>>>>>>>>>>> ]]> 

Si los comentarios HTML incluyen otras etiquetas, esas soluciones también rompería el texto como este:

<!-- This section commented out. 
    <B>You can't see me!</B> 
--> 
+0

A la sugerencia de secuencia de comandos: http://www.cpan.org/authors/id/T/TO/TOMC/scripts/striphtml.gz - esto borra todo ¿Cómo puedo modificar este código solo para dejar ciertas etiquetas html? Aparte de eso, funciona bien. – PKHunter

14

Definitivamente debe echarle un vistazo al HTML::Restrict que le permite eliminar o restringir las etiquetas HTML permitidas. Un ejemplo mínima que despoja de todas las etiquetas HTML:

use HTML::Restrict; 

my $hr = HTML::Restrict->new(); 
my $processed = $hr->process('<b>i am bold</b>'); # returns 'i am bold' 

yo recomendaría mantenerse alejado de HTML :: Gaza porque it breaks utf8 encoding.

+0

Ojalá hubiera leído esta respuesta hace unas semanas. – Steven

+0

No funciona con Perl 5.8.x. Es un súper programa, pero sería bueno saber cuál es su estructura de soporte. – PKHunter

+0

Además, no estoy seguro de si hay alguna manera de dejar las etiquetas (etiquetas permitidas) que no tienen etiquetas de abrir y cerrar. El ejemplo '
' es difícil de identificar. – PKHunter

Cuestiones relacionadas