web-dev-qa-db-fra.com

Comment puis-je supprimer les balises HTML d'une chaîne dans ASP.NET?

Avec ASP.NET, comment puis-je supprimer les balises HTML d’une chaîne donnée (c’est-à-dire ne pas utiliser de regex)? Je cherche quelque chose comme le strip_tags de PHP.

Exemple:

<ul><li>Hello</li></ul>

Sortie:

"Bonjour"

J'essaie de ne pas réinventer la roue, mais je n'ai encore rien trouvé qui réponde à mes besoins.

118
daniel

S'il supprime simplement tout balises HTML d'une chaîne, cela fonctionne également avec regex. Remplacer:

<[^>]*(>|$)

avec la chaîne vide, globalement. N'oubliez pas de normaliser la chaîne par la suite, en remplaçant:

[\s\r\n]+

avec un seul espace et en coupant le résultat. Vous pouvez éventuellement remplacer toutes les entités de caractères HTML par les caractères réels.

Remarque

  1. Il existe une limitation: HTML et XML autorisent > dans les valeurs d'attribut. Cette solution (will} _ renvoie un balisage brisé lorsqu’elle rencontre de telles valeurs.
  2. La solution est techniquement sûre, comme dans: Le résultat ne contiendra jamais quoi que ce soit qui pourrait être utilisé pour effectuer un script intersite ou pour casser une mise en page. Ce n'est tout simplement pas très propre.
  3. Comme avec toutes les choses HTML et regex:
    Utilisez un analyseur approprié si vous devez le faire correctement en toutes circonstances
104
Tomalak

Allez télécharger HTMLAgilityPack, maintenant! ;) Lien de téléchargement

Cela vous permet de charger et d’analyser du HTML. Ensuite, vous pouvez naviguer dans le DOM et extraire les valeurs internes de tous les attributs. Sérieusement, il vous faudra environ 10 lignes de code au maximum. C’est l’une des meilleures bibliothèques gratuites en .net.

Voici un échantillon:

            string htmlContents = new System.IO.StreamReader(resultsStream,Encoding.UTF8,true).ReadToEnd();

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(htmlContents);
            if (doc == null) return null;

            string output = "";
            foreach (var node in doc.DocumentNode.ChildNodes)
            {
                output += node.InnerText;
            }
70
Serapth
Regex.Replace(htmlText, "<.*?>", string.Empty);
62
user95144
protected string StripHtml(string Txt)
{
    return Regex.Replace(Txt, "<(.|\\n)*?>", string.Empty);
}    

Protected Function StripHtml(Txt as String) as String
    Return Regex.Replace(Txt, "<(.|\n)*?>", String.Empty)
End Function
11
meramez

J'ai posté ceci sur les forums asp.net, et cela semble toujours être l'une des solutions les plus faciles sur le marché. Je ne garantirai pas que c'est le plus rapide ou le plus efficace, mais c'est assez fiable. En .NET, vous pouvez utiliser les objets HTML Web Control. Tout ce que vous avez vraiment besoin de faire est d'insérer votre chaîne dans un objet HTML temporaire tel qu'un DIV, puis d'utiliser le "InnerText" intégré pour récupérer tout le texte non contenu dans les balises. Voir ci-dessous pour un exemple simple en C #:


System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;
6
Michael Tipton

J'ai écrit une méthode assez rapide en C # qui bat l'enfer de la regex. Il est hébergé dans an article sur CodeProject.

Parmi ses avantages, on peut citer, parmi de meilleures performances, la possibilité de remplacer des entités HTML nommées et numérotées (comme &amp;amp; et &203;) et le remplacement des blocs de commentaires, etc.

Veuillez lire l'article connexe sur CodeProject .

Je vous remercie.

5
Andrei Rînea

Pour ceux d'entre vous qui ne peuvent pas utiliser HtmlAgilityPack, le lecteur XML .NET est une option. Cela peut échouer avec du HTML bien formaté, donc ajoutez toujours une capture avec regx comme sauvegarde. Notez que ceci n’est PAS rapide, mais cela fournit une bonne opportunité pour la vieille école de déboguer.

public static string RemoveHTMLTags(string content)
    {
        var cleaned = string.Empty;
        try
        {
            StringBuilder textOnly = new StringBuilder();
            using (var reader = XmlNodeReader.Create(new System.IO.StringReader("<xml>" + content + "</xml>")))
            {
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Text)
                        textOnly.Append(reader.ReadContentAsString());
                }
            }
            cleaned = textOnly.ToString();
        }
        catch
        {
            //A tag is probably not closed. fallback to regex string clean.
            string textOnly = string.Empty;
            Regex tagRemove = new Regex(@"<[^>]*(>|$)");
            Regex compressSpaces = new Regex(@"[\s\r\n]+");
            textOnly = tagRemove.Replace(content, string.Empty);
            textOnly = compressSpaces.Replace(textOnly, " ");
            cleaned = textOnly;
        }

        return cleaned;
    }
4
Bucket
string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);
3
Ahmet BUTUN

Pour ceux qui se plaignent du fait que la solution de Michael Tiptop ne fonctionne pas, voici la méthode .Net4 +:

public static string StripTags(this string markup)
{
    try
    {
        StringReader sr = new StringReader(markup);
        XPathDocument doc;
        using (XmlReader xr = XmlReader.Create(sr,
                           new XmlReaderSettings()
                           {
                               ConformanceLevel = ConformanceLevel.Fragment
                               // for multiple roots
                           }))
        {
            doc = new XPathDocument(xr);
        }

        return doc.CreateNavigator().Value; // .Value is similar to .InnerText of  
                                           //  XmlDocument or JavaScript's innerText
    }
    catch
    {
        return string.Empty;
    }
}
1
Annie

Pour le deuxième paramètre, c.-à-d. gardez quelques balises, vous aurez peut-être besoin d'un code comme celui-ci en utilisant HTMLagilityPack:

public string StripTags(HtmlNode documentNode, IList keepTags)
{
    var result = new StringBuilder();
        foreach (var childNode in documentNode.ChildNodes)
        {
            if (childNode.Name.ToLower() == "#text")
            {
                result.Append(childNode.InnerText);
            }
            else
            {
                if (!keepTags.Contains(childNode.Name.ToLower()))
                {
                    result.Append(StripTags(childNode, keepTags));
                }
                else
                {
                    result.Append(childNode.OuterHtml.Replace(childNode.InnerHtml, StripTags(childNode, keepTags)));
                }
            }
        }
        return result.ToString();
    }

Plus d'explications sur cette page: http://nalgorithm.com/2015/11/20/strip-html-tags-of-an-html-in-c-strip_html-php-equivalent/

0
Yuksel Daskin

J'ai examiné les solutions basées sur Regex suggérées ici, et elles ne me procurent aucune confiance, sauf dans les cas les plus triviaux. Un angle entre crochets dans un attribut est tout ce qu'il faudrait pour casser, sans parler du code HTML mal formé issu de la nature. Et qu'en est-il des entités comme &amp;? Si vous souhaitez convertir HTML en texte brut, vous devez également décoder les entités.

Je propose donc la méthode ci-dessous.

En utilisant HtmlAgilityPack , cette méthode d’extension supprime efficacement toutes les balises HTML d’un fragment html. Décode également les entités HTML comme &amp;. Renvoie uniquement les éléments de texte internes, avec une nouvelle ligne entre chaque élément de texte.

public static string RemoveHtmlTags(this string html)
{
        if (String.IsNullOrEmpty(html))
            return html;

        var doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(html);

        if (doc.DocumentNode == null || doc.DocumentNode.ChildNodes == null)
        {
            return WebUtility.HtmlDecode(html);
        }

        var sb = new StringBuilder();

        var i = 0;

        foreach (var node in doc.DocumentNode.ChildNodes)
        {
            var text = node.InnerText.SafeTrim();

            if (!String.IsNullOrEmpty(text))
            {
                sb.Append(text);

                if (i < doc.DocumentNode.ChildNodes.Count - 1)
                {
                    sb.Append(Environment.NewLine);
                }
            }

            i++;
        }

        var result = sb.ToString();

        return WebUtility.HtmlDecode(result);
}

public static string SafeTrim(this string str)
{
    if (str == null)
        return null;

    return str.Trim();
}

Si vous êtes vraiment sérieux, vous voudrez également ignorer le contenu de certaines balises HTML (<script>, <style>, <svg>, <head>, <object>!) Car elles ne contiennent probablement pas de contenu lisible au sens que nous recherchons. Ce que vous ferez là-bas dépendra de votre situation et de la distance que vous souhaitez parcourir, mais utiliser HtmlAgilityPack serait assez simple pour ajouter des balises sélectionnées à la liste blanche ou à la liste noire.

Si vous restituez le contenu sur une page HTML, assurez-vous de bien comprendre la vulnérabilité XSS et comment l'éviter - c.-à-d., Codez toujours le texte saisi par l'utilisateur qui est restitué sur une page HTML (> devient &gt; etc.) .

0
saille
using System.Text.RegularExpressions;

string str = Regex.Replace(HttpUtility.HtmlDecode(HTMLString), "<.*?>", string.Empty);
0
Karan