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.
<ul><li>Hello</li></ul>
"Bonjour"
J'essaie de ne pas réinventer la roue, mais je n'ai encore rien trouvé qui réponde à mes besoins.
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:
>
dans les valeurs d'attribut. Cette solution (will} _ renvoie un balisage brisé lorsqu’elle rencontre de telles valeurs.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;
}
Regex.Replace(htmlText, "<.*?>", string.Empty);
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
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;
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;
et &203;
) et le remplacement des blocs de commentaires, etc.
Veuillez lire l'article connexe sur CodeProject .
Je vous remercie.
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;
}
string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);
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;
}
}
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/
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 &
? 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 &
. 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 >
etc.) .
using System.Text.RegularExpressions;
string str = Regex.Replace(HttpUtility.HtmlDecode(HTMLString), "<.*?>", string.Empty);