Alejandro B. Martin - Blog de Asp.Net y MsSQL

Agosto 15, 2008

Eliminar cualquier conjunto de etiquetas Html (tags) de apertura y cierre

Necesitaba un código Regex que me eliminase todas las etiquetas <a href ..></a> (de apertura y cierre) de cualquier cadena de texto (string).

ANTES:
“mi web es <a href=”miweb.com”>www.miweb.com</a> veréis que chula, ver también <a href=’www.otraweb.com’ target=”_blank”>otraweb.com</ a>”

EL RESULTADO QUE SE QUIERE OBTENER:
“mi web es www.miweb.com veréis que chula, ver también otraweb.com”


Más de 1 hora buscando por internet y no he encontrado ningún código que me solucionase el problema.

He desarrollado una función, que además de solucionar el anterior problema, sirve para eliminar cualquier etiqueta HTML de las que tienen cierre.

El siguiente código es válido para eliminar etiquetas de apertura y cierre de cualquier cadena de caracteres, tales como; <a href, <div, <span, etc .., es decir, todas aquellas que tienen asociada una etiqueta de cierre; </a>, </div>, </span>, etc ..
Este código no es válido para eliminar etiquetas que no tengan asociada una de cierre; <br> (o <br/>), <hr>, etc .

La siguiente función eliminará todas las etiquetas tag html, incluyendo sus parámetros, pero mantendrá el texto contenido entre ellas.

Ideal para formatear código HTMl a texto plano.

    ''' <summary>
    ''' Elimina todas las etiquetas html (tags) de apertura y cierre. Mantiene (no elimina) el texto contenido entre ellas.
    ''' </summary>
    ''' <param name="str">La cadena de texto (string) sobre la cuál se quieren eliminar las etiquetas</param>
    ''' <param name="TagStart">Determinada etiqueta para la cual se quieran eliminar sus aperturas y cierres. 
    ''' Debe incluirse el char. de apertura seguido del nombre de la etiqueta</param>
    ''' ej: <a , <div , <span , etc .. 
    ''' <returns>Devuelve la cadena de texto del arg. "str", sin las etiquetas de apertura y cierre.</returns>
    ''' <remarks>Por Alejandro Barrada Martín</remarks>
    Public Function RemoveHtmlTagsStartEnd(ByVal str As String, ByVal TagStart As String) As String
        Dim result As String = Nothing
        Dim HtmlTagEnd As String = TagStart.Replace("<", "").Replace("< ", "")
        For i As Integer = 0 To str.Length - 1
            If Not i >= str.Length - 1 - TagStart.Length Then
                If str.Substring(i, TagStart.Length) = TagStart Then
                    For j As Integer = i To str.Length - 1
                        If Not j >= str.Length - 1 - 2 Then
                            If str.Substring(j, 2) = """>" _
                            Or str.Substring(j, 2) = "'>" Or str.Substring(j, 2) = " >" Then
                                i = j + 2
                                Exit For
                            End If
                        End If
                    Next
                    For j As Integer = i To str.Length - 1
                        If Not j >= str.Length - 1 - HtmlTagEnd.Length - 1 Then
                            If str.Substring(j, 2 + HtmlTagEnd.Length) = "</" & HtmlTagEnd Then
                                i = j + 2 + HtmlTagEnd.Length
                                Exit For
                            ElseIf str.Substring(j, 3 + HtmlTagEnd.Length) = "</ " & HtmlTagEnd _
                            Or str.Substring(j, 3 + HtmlTagEnd.Length) = "< /" & HtmlTagEnd Then
                                i = j + 3 + HtmlTagEnd.Length
                                Exit For
                            Else
                                result &= str.Substring(j, 1)
                            End If
                        End If
                    Next
                Else
                    result &= str.Substring(i, 1)
                End If
            Else
                result &= str.Substring(i, 1)
            End If
        Next
        Return result
    End Function

Ejemplo de llamada a dicha función:

                Dim textoHtml As String _
                = "mi web es <a href='miweb.com'>www.miweb.com</a> veréis que chula" _
                 & ", ver también <a href='www.otraweb.com' target='_blank'>otraweb.com</ a>"
                Dim textoSinEtiquetasAHref As String = RemoveHtmlTagsStartEnd(textoHtml, "<a")
                Response.Write(textoSinEtiquetasAHref)

Como resultado se tendrá:

mi web es www.miweb.com veréis que chula, ver también otraweb.com


Finalizo el post indicando que, si alguien conoce algún patrón ReGex para lo siguiente, que postee, y tras comprobarlo lo publicaré en este mismo post, para que sea de ayuda a otros programadores.
Patrones Pendientes de Publicación:

1) Cómo eliminar etiquetas de apertura y cierre para una determinada etiqueta, es decir, eliminar <a href y todos sus parametros> mantener el texto entre las apertura y cierre </a eliminar etiqueta cierre>, pero usando algún patrón de expresión regular

2) Cómo eliminar todas las etiquetas (apertura y cierre, y también sólo apertura) de una cadena.
Ideal para los que quieran convertir un código HTML a texto plano.

Return system.Text.RegularExpressions.Regex.Replace("CadenaStringALaQueQuitarTodasLasTags", "<(.|\n)*?>", "")

A COLABORAR !

Febrero 27, 2008

Formatear cadenas de Texto/String como númericas con o sin decimales - Regex - Expresiones Regulares

En este post voy a explicar cómo convertir cualquier cadena de texto que contenga letras y números de cualquier índole y posibilidad, a formato numérico utilizando para ello las expresiones regulares (regex : regular expressions). Es decir, recoger números, números con decimales, con o sin puntos y/o comas de separación, así como cualquiera de las anteriores.

Escribo este post, pues me ha resultado bastante complicado dar con la solución (dar con la cadena regex) adecuada para convertir cadenas de texto (strings) a números con o sin decimales, con o sin delimitadores (millares, etc ..).


Hmnn no hace falta que te leas todo este tocho. en este post te abrevio y te doy posiblemente la solución regex que buscasBREVE INTRO - REGEX EN .NET - RECOGER CADENA CON SÓLO SUS NUMEROS

No te asustes por el libro !, en este post encontrarás la solución para recoger de cadenas string, números con todo tipo de formato.

Primero una breve intro. sobre cómo usar las regular expressions en .Net (para más información sobre dicho mundo, al final de página referencio algunos links interesantes para aprender).

Para poder usar expresiones reguares a la hora de recojer, buscar o sustituir cadenas string, .Net nos provee del objeto regex. Dicho objeto viene cargado por defecto salvo que estés utilizando un proyecto de librería de clases en cuyo caso deberás importar su espacio de nombre:

Imports System.Text.RegularExpressions

Bien pues, ahora explico cómo utilizar dicho objeto para nuestro cometido, que tal cual reza el titular de este post, trata de obtener cadenas numéricas.
Empezaremos con algo sencillo para acabar ir avanzando hasta acabar con algo más complejo (decimales y separadores).

APRENDIENDO A USAR EL OBJETO

regex regular expressions, expresiones regulares numéricas en .net

Tomemos como ejemplo las siguientes variables:

Dim CadenaDeTextoSinFormato_comoNumeroEntero As String = “Importe : 150 Euros”

Dim ResultadoQueQueremosObtener_comoNumeroEntero As String

  • Para encontrar (seleccionar) una cadena que cumpla con determinado criterio usamos:

Dim CriterioDeExpresionRegularQueDebemosAplicar As String

ResultadoQueQueremosObtener_comoNumeroEntero = Regex.Match(CadenaDeTextoSinFormato_comoNumeroEntero, CriterioDeExpresionRegularQueDebemosAplicar).Value

play.gif EJ.: RECOJER NUMEROS

Empezaremos con algo sencillo, tomando como ejemplo las variables anteriores, podemos usar cualquiera de las siguientes expresiones regulares para obtener el/los números de la cadena de texto “importe : 150 Euros”. Podemos usar:

  • [d]+
    • Donde + indica que obtendrá todos los caracteres que sigan. Puede ser [d](2) si sólo queremos coger 2 caracteres (numéricos)
  • [0-9]+
    • Donde 0-9 indica que los caracteres deben estar entre el 0 y el 9

Que bien, dirás, ..
Pues si pero no, jj,

RECOGER TODO TIPO DE NUMÉRICOS - DESDE SIMPLES A COMPLEJOS

Si tubiésemos diferentes números, en diferente formato, con o sin Decimales, etc., en fín algo más complicado ..

Supongamos que (como el aquí presente), estás recogiendo datos de los que su formato sea variable(dinámico) .

numeros de todo tipo ¿?

Imagina que estas desarrollando una aplicación que debe guardar datos con formato numérico (integer, decimal, money o lo que sea).
Pero que tu aplicativo sólo recibe cadenas de texto, las que además de poder contener números - lo que tu app. debe recoger (importes (precios u otras)) - dichas cadenas pueden contener:

  • Cadenas de texto con un integer (entero numérico)
    • “Importe : 150 euros” o bien “€150″ <— este último caso esta en formato inglés (el símbolo de la moneda va antes que su cantidad)
  • Números con decimal o decimales
    • “Kilogramos : 1.55 “, “150 euros”, ..
  • Números con separadores
    • “1,400,000 euros”, “150.30 Kb”, ..
  • Números con decimales y con separadores
  • “1.999,99 euros”, ..
  • Con formato a la inglesa (el punto por la coma y viceversa)
  • “1,999.54 euros”, “150 euros”, ..

Como veis, són muchos los casos que nos podemos encontrar, más aún si se trata de formatos diferentes según países (ver los 2ºs ejemplos).

En este post no voy a exponer todas las expresiones regulares que harían falta para recojer los valores anteriormente expuestos en cualquier combinación de los mismos pues el post sería larguíssimo.

Pero basta con deciros que

  • Por una parte expongo abajo varios enlaces; incluidos portales donde se pueden encontrar centenas de expresiones regex para til fin.
  • Pero y Más aún por otro, y el mejor de todos (tras búscar y buscar, probar y probar) ..
  • OS MUESTRO LA QUE POSIBLEMENTE SEA LA ÚNICA EXPRESION REGULAR QUE NECESITÉIS PARA OBTENER DATOS NUMÉRICOS, ESTÉN EN EL FORMATO QUE ESTÉN

b(?:d{1,3}(?(?=[,.])[,.](?:d{3}(?:[.,](?=d)|b)|(?:b|d{1,2}))|b))+

Vale que sea muy larga, pero con dicha regex conseguireis cualquier valor numérico que se encuentre en una cadena de caracteres, tal cuál estuviese excrito.
Así pues, con 1 misma expresión extraeremos siempre el contenido numérico esté en el formato que esté.

A los que se pregunten, ¿Porqué no puedo usar otra expresión regular más pequeña?, les respondo.
Si bien es cierto y correcto utilizar expresiones más sencillas, debo advertir, que si os cambian el formato de las cifras, vuestro regex fallará o no recogerá correctamente los datos.

play.gif RESUMEN

Si quereis capturar númericos de los que su formato y expresión pueda variar; con o sin decimales, con o sín separadores de millar y otros y, estén en el formato que estén (inglés, americano, Español, ..) entonces, así como si quereis despreocupación, utilizad dicha expresión, que repito s:

b(?:d{1,3}(?(?=[,.])[,.](?:d{3}(?:[.,](?=d)|b)|(?:b|d{1,2}))|b))+

Nota* Si en una misma cadena string existen varios números separados, es decir por ejemplo “unidades : 3 — importe x ud.: 5,5 — total: 16,5 euros” debéis separar antes (dividir) la cadena en 3 (o tantas partes como números que querais coger contenga)

_

_

_

Links relacionados

www.regular-expressions.info <– info con manuales

http://regexlib.com/DisplayPatterns.aspx?cattabindex=2&categoryid=3&p=2 <– Montón de expresiones con ejemplos de los resultados que se pueden conseguir, en concreto dicha url apunta a la página con exp. reg. para números, eso sí, la gran cadena mágica que aquí os he expuesto no creo que la encontrareis.

Espero que os sirva de ayuda y que os ahorre tiempo

Saludos

Copyright 27 Febrero 2008 © Alejandro Barrada Martin - Reservados todos los derechos salvo consentimiento del autor.
El autor cede los derechos de publicación del presente artículo siempre y cuando se mencione al mismo y a esta url-dirección web.

Blog de WordPress.com.