Pregunta

Estoy buscando una forma rápida de analizar las etiquetas HTML de una cadena de ColdFusion. Estamos tirando en un feed RSS, que podría potencialmente tener nada en ella. entonces estamos haciendo alguna manipulación de la información y luego la volviera a expulsar a otro lugar. Actualmente estamos haciendo esto con una expresión regular. ¿Hay una mejor manera de hacer esto?

<cfloop from="1" to="#ArrayLen(myFeed.item)#" index="i">
  <cfset myFeed.item[i].description.value = 
   REReplaceNoCase(myFeed.item[i].description.value, '<(.|\n)*?>', '', 'ALL')>
</cfloop>

Estamos utilizando ColdFusion 8.

¿Fue útil?

Solución

Aviso Legal Soy un firme defensor de la utilización de un analizador adecuado (en lugar de expresiones regulares) para analizar HTML. Sin embargo, esta cuestión no se trata de analisis de de HTML, sino de destruyendo ella. Para todas las tareas que van más allá de eso, utilice un analizador.


Creo que su expresión regular es bueno. Mientras no hay nada más que eliminar todas las etiquetas HTML de la entrada, utilizando una expresión regular como la suya es seguro.

Cualquier otra cosa sería probablemente más problemas de lo que vale, pero que podría escribir una pequeña función que recorra la cadena char-por-char de una vez y elimina todo lo que está dentro de los soportes de etiquetas - ej .:

  • interruptor en un "Intag" bandera tan pronto como se encuentra con un carácter "<",
  • apagarlo tan pronto como se encuentra con ">"
  • caracteres de copia a la cadena de salida, siempre y cuando el indicador está apagado
  • para el rendimiento, use un objeto StringBuilder de Java en lugar de la concatenación de cadenas

Para una parte de alta demanda de su aplicación, esto puede ser más rápido que la expresión regular. Pero la expresión regular está limpio y probablemente lo suficientemente rápido.

Tal vez esta expresión regular modificado tiene algunas ventajas para usted:

<[^>]*(?:>|$)
  • atrapa etiquetas sin cerrar al final de la cadena
  • [^>]* es mejor que (.|\n)

El uso de REReplaceNoCase() es innecesaria cuando no hay cartas reales en el patrón. Entre mayúsculas y minúsculas coincidencia de expresiones regulares es más lento que hacerlo de casos y con sensibilidad.

Otros consejos

HTML no es un lenguaje regular, por lo que el uso de expresiones regulares en (no controlado) HTML es algo que se debe hacer con mucho cuidado (si acaso).

Considere, por ejemplo, la siguiente válida segmento de HTML:

<img src="boat.jpg" alt="a boat" title="My boat is > everything! I <3 my boat!">

Se habrá dado cuenta cómo el resaltador de sintaxis está ahogando en que -. Como será la expresión regular existente que se ha ofrecido

A menos que pueda ser seguro que la cadena está procesando no contendrá código HTML similar a la anterior, se debe evitar hacer suposiciones / compromiso, que una sola / pura ruta de expresiones regulares que obligaría a hacer.

(Nota:. El mismo problema se aplica al método sugerido char-por-char también)


Para resolver el problema, se debe utilizar un analizador DOM para analizar su cadena en un objeto HTML, bucle a través de cada elemento y la conversión a texto.

Si usted tiene XHTML, puede utilizar XmlParse() CF para producir el objeto que luego se puede bucle sin embargo. Si podría ser HTML no XML entonces no hay opción integrada con CF8, por lo que tendrá que investigar las opciones en Java / etc.

Yo uso este:

REReplaceNoCase(text, "<[^[:space:]][^>]*>", "", "ALL");

99% de los casos funciona bien.

La mejor manera es por lo general para obligar a < &lt; y > a &gt;. De esta manera no están haciendo suposiciones sobre la naturaleza del mensaje. Alguien puede estar hablando de <tags> o tratando de ser <<expressive>> o describir un <Ctrl>+C golpe de teclado o el uso de las matemáticas 1 < x > 3. Incluso emoticones podrían desencadenar la <8P X> expresiones regulares

<cfloop from="1" to="#ArrayLen(myFeed.item)#" index="i">
    <cfset myFeed.item[i].description.value = ReplaceList(myFeed.item[i].description.value, '<,>', '&lt;,&gt;')>
</cfloop>

cflib es su amigo: stripHTML

<cfset a = "<b><font color = 'red'>(PCB) <1 ppm </font></b>">

<cfset b = REReplaceNoCase(a, "<[^><]*>", '', 'ALL')>

<cfdump var="#b#">

salida b = "(PCB) <1 ppm"

La expresión regular "<[^> <] *>" eliminará todas las etiquetas y los caracteres dentro de esas etiquetas y no quitar las etiquetas individuales como que puede ser utilizado como menor o mayor que el símbolo de cadena

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top