Elimine las etiquetas HTML de la cadena, incluido & nbsp en C #


83

¿Cómo puedo eliminar todas las etiquetas HTML, incluidas & nbsp, usando expresiones regulares en C #? Mi cuerda parece

  "<div>hello</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div>"

9
No use una expresión regular, consulte el HTML Agility Pack. stackoverflow.com/questions/846994/how-to-use-html-agility-pack
Tim

Gracias Tim, pero la aplicación es bastante grande e intacta, agregar o descargar un paquete de agilidad html no funcionará.
rampuriyaaa

Respuestas:


196

Si no puede utilizar una solución orientada al analizador HTML para filtrar las etiquetas, aquí tiene una expresión regular simple.

string noHTML = Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", "").Trim();

Idealmente, debería hacer otra pasada a través de un filtro de expresiones regulares que se encarga de varios espacios como

string noHTMLNormalised = Regex.Replace(noHTML, @"\s{2,}", " ");

Todavía no lo he probado tanto como lo necesito, pero funcionó mejor de lo que esperaba. Publicaré el método que escribí a continuación.
Don Rolling

Una coincidencia perezosa ( <[^>]+?>según @David S.) podría hacer esto un poco más rápido, pero solo usé esta solución en un proyecto en vivo, muy feliz +1 :)
Gone Coding

Regex.Replace (inputHTML, @ "<[^>] +> | & nbsp | \ n;", "") .Trim (); \ n no se eliminará
Mahesh Malpani

3
Recomendaría agregar un espacio en lugar de una cadena vacía, estamos capturando espacios adicionales de cualquier maneraRegex.Replace(inputHTML, @"<[^>]+>|&nbsp;", " ")
Tauseef

2
@Tauseef Si usa un espacio en la primera llamada de reemplazo, puede terminar dejando espacios donde no había ninguno en la entrada original. Digamos que recibe Sound<b>Cloud</b>como entrada; terminará con Sound Cloudlo que debería haber sido eliminado SoundCloudporque así es como se muestra en HTML.
Ravi Thapliyal

31

Tomé el código de @Ravi Thapliyal e hice un método: es simple y puede que no limpie todo, pero hasta ahora está haciendo lo que necesito que haga.

public static string ScrubHtml(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>|&nbsp;", "").Trim();
    var step2 = Regex.Replace(step1, @"\s{2,}", " ");
    return step2;
}

16

He estado usando esta función por un tiempo. Elimina prácticamente cualquier html desordenado que puedas lanzar y deja el texto intacto.

        private static readonly Regex _tags_ = new Regex(@"<[^>]+?>", RegexOptions.Multiline | RegexOptions.Compiled);

        //add characters that are should not be removed to this regex
        private static readonly Regex _notOkCharacter_ = new Regex(@"[^\w;&#@.:/\\?=|%!() -]", RegexOptions.Compiled);

        public static String UnHtml(String html)
        {
            html = HttpUtility.UrlDecode(html);
            html = HttpUtility.HtmlDecode(html);

            html = RemoveTag(html, "<!--", "-->");
            html = RemoveTag(html, "<script", "</script>");
            html = RemoveTag(html, "<style", "</style>");

            //replace matches of these regexes with space
            html = _tags_.Replace(html, " ");
            html = _notOkCharacter_.Replace(html, " ");
            html = SingleSpacedTrim(html);

            return html;
        }

        private static String RemoveTag(String html, String startTag, String endTag)
        {
            Boolean bAgain;
            do
            {
                bAgain = false;
                Int32 startTagPos = html.IndexOf(startTag, 0, StringComparison.CurrentCultureIgnoreCase);
                if (startTagPos < 0)
                    continue;
                Int32 endTagPos = html.IndexOf(endTag, startTagPos + 1, StringComparison.CurrentCultureIgnoreCase);
                if (endTagPos <= startTagPos)
                    continue;
                html = html.Remove(startTagPos, endTagPos - startTagPos + endTag.Length);
                bAgain = true;
            } while (bAgain);
            return html;
        }

        private static String SingleSpacedTrim(String inString)
        {
            StringBuilder sb = new StringBuilder();
            Boolean inBlanks = false;
            foreach (Char c in inString)
            {
                switch (c)
                {
                    case '\r':
                    case '\n':
                    case '\t':
                    case ' ':
                        if (!inBlanks)
                        {
                            inBlanks = true;
                            sb.Append(' ');
                        }   
                        continue;
                    default:
                        inBlanks = false;
                        sb.Append(c);
                        break;
                }
            }
            return sb.ToString().Trim();
        }

Solo para confirmar: la función SingleSpacedTrim () hace lo mismo que string noHTMLNormalised = Regex.Replace (noHTML, @ "\ s {2,}", ""); de la respuesta de Ravi Thapliyal?
Jimmy

@Jimmy, por lo que puedo ver, esa expresión regular no captura pestañas individuales o líneas nuevas como lo hace SingleSpacedTrim (). Sin embargo, ese podría ser un efecto deseable, en ese caso simplemente elimine los casos según sea necesario.
David S.

Bien, pero parece que reemplaza las comillas simples y dobles con espacios en blanco también, aunque no están en la lista " notOkCharacter ", ¿o me falta algo allí? ¿Esta parte de los métodos de decodificación / codificación se llama al principio? ¿Qué sería necesario para mantener intactos a estos personajes?
vm370

4
var noHtml = Regex.Replace(inputHTML, @"<[^>]*(>|$)|&nbsp;|&zwnj;|&raquo;|&laquo;", string.Empty).Trim();

1

He usado el código de @RaviThapliyal y @Don Rolling, pero hice una pequeña modificación. Ya que estamos reemplazando & nbsp con una cadena vacía, pero en su lugar & nbsp debería reemplazarse con un espacio, agregamos un paso adicional. Me funcionó a las mil maravillas.

public static string FormatString(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>", "").Trim();
    var step2 = Regex.Replace(step1, @"&nbsp;", " ");
    var step3 = Regex.Replace(step2, @"\s{2,}", " ");
    return step3;
}

Se usó & nbps sin punto y coma porque el Stack Overflow lo estaba formateando.


0

esta:

(<.+?> | &nbsp;)

coincidirá con cualquier etiqueta o &nbsp;

string regex = @"(<.+?>|&nbsp;)";
var x = Regex.Replace(originalString, regex, "").Trim();

entonces x = hello


0

La desinfección de un documento Html implica muchas cosas complicadas. Este paquete puede ser de ayuda: https://github.com/mganss/HtmlSanitizer


Creo que es más contra los ataques XSS que normalizar html
Revious

1
@Revious Creo que tienes razón. Tal vez mi respuesta no esté relacionada mucho con la pregunta del OP, ya que no mencionaron el propósito de eliminar las etiquetas html. Pero si el propósito es prevenir ataques, como sucede en muchos casos, entonces usar un desinfectante ya desarrollado puede ser un mejor enfoque. Por cierto, no tengo conocimiento sobre cuál es el significado de normalizar html .
Ehsan88

0

HTML está en su forma básica solo XML. Puede analizar su texto en un objeto XmlDocument y, en el elemento raíz, llamar a InnerText para extraer el texto. Esto eliminará todas las etiquetas HTML en cualquier forma y también tratará con caracteres especiales como & lt; & nbsp; todo de una vez.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.