Comment utiliser une expression régulière C# pour remplacer/supprimer toutes les balises HTML, y compris les crochets d'angle ? Quelqu'un peut-il m'aider avec le code ?
Réponses
Trop de publicités?Comme nous l'avons souvent dit, vous ne devez pas utiliser d'expressions régulières pour traiter des documents XML ou HTML. Elles ne sont pas très performantes avec les documents HTML et XML, car il n'existe aucun moyen d'exprimer les structures imbriquées de manière générale.
Vous pourriez utiliser ce qui suit.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Cela fonctionnera dans la plupart des cas, mais il y aura des cas (par exemple CDATA contenant des crochets d'angle) où cela ne fonctionnera pas comme prévu.
La bonne réponse est de ne pas faire ça, mais d'utiliser la fonction Pack Agilité HTML .
Modifié pour ajouter :
Pour reprendre sans vergogne le commentaire de Jesse ci-dessous, et pour éviter d'être accusé d'avoir mal répondu à la question après tout ce temps, voici un extrait simple et fiable utilisant le pack HTML Agility qui fonctionne même avec les morceaux de HTML les plus imparfaits et capricieux :
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Properties.Resources.HtmlContents);
var text = doc.DocumentNode.SelectNodes("//body//text()").Select(node => node.InnerText);
StringBuilder output = new StringBuilder();
foreach (string line in text)
{
output.AppendLine(line);
}
string textOnly = HttpUtility.HtmlDecode(output.ToString());
Il y a très peu de cas défendables pour l'utilisation d'une expression régulière pour analyser le HTML, car le HTML ne peut pas être analysé correctement sans une connaissance du contexte qui est très difficile à fournir, même dans un moteur regex non traditionnel. Vous pouvez y arriver en partie avec une RegEx, mais vous devrez faire des vérifications manuelles.
Html Agility Pack peut vous fournir une solution robuste qui réduira la nécessité de corriger manuellement les aberrations qui peuvent résulter du traitement naïf du HTML comme une grammaire sans contexte.
Une expression régulière peut vous permettre d'obtenir ce que vous voulez la plupart du temps, mais elle échouera dans des cas très courants. Si vous pouvez trouver un analyseur syntaxique meilleur/plus rapide que HTML Agility Pack, allez-y, mais s'il vous plaît, ne soumettez pas le monde à plus de piratage HTML cassé.
La question est trop vaste pour qu'on puisse y répondre de manière définitive. Parlez-vous de la suppression de toutes les balises d'un document HTML du monde réel, comme une page Web ? Si c'est le cas, vous devriez le faire :
- supprimer la déclaration <!DOCTYPE ou le prologue <?xml] s'ils existent
- supprimer tous les commentaires SGML
- supprimer l'ensemble de l'élément HEAD
- supprimer tous les éléments script et STYLE
- faire Grabthar-sait-quoi avec les éléments FORM et TABLE
- supprimer les balises restantes
- supprimer les séquences < ![CDATA[ et ]]> des sections CDATA mais laisser leur contenu intact
Ce n'est qu'un aperçu de ce que je pense. Je suis sûr qu'il y en a d'autres. Une fois que vous aurez fait tout cela, vous vous retrouverez avec des mots, des phrases et des paragraphes accolés à certains endroits, et de grands morceaux d'espaces vides inutiles à d'autres.
Mais, en supposant que vous ne travaillez qu'avec un fragment et que vous pouvez vous en sortir en supprimant simplement toutes les balises, voici la regex que j'utiliserais :
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
La mise en correspondance des chaînes de caractères à guillemets simples et doubles dans leurs propres alternatives suffit à régler le problème des crochets d'angle dans les valeurs d'attribut. Je ne vois pas la nécessité de faire correspondre explicitement les noms d'attributs et d'autres éléments à l'intérieur de la balise, comme le fait la regex dans la réponse de Ryan ; la première alternative gère tout cela.
Au cas où vous vous demanderiez à propos de ces (?>...)
les constructions, elles sont groupes atomiques . Ils rendent la regex un peu plus efficace, mais surtout, ils empêchent le retour en arrière, ce à quoi il faut toujours faire attention quand on mélange l'alternance et les quantificateurs imbriqués comme je l'ai fait. Je ne pense pas vraiment que ce soit un problème ici, mais je sais que si je ne le mentionne pas, quelqu'un d'autre le fera ;-)
Cette regex n'est pas parfaite, bien sûr, mais elle est probablement aussi bonne que ce dont vous aurez jamais besoin.
@JasonTrue a raison, la suppression des balises HTML ne doit pas être effectuée par des expressions régulières.
Il est assez simple de supprimer les balises HTML à l'aide de HtmlAgilityPack :
public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}
- Réponses précédentes
- Plus de réponses