Comment utiliser l'expression régulière C # pour remplacer / supprimer toutes les balises HTML, y compris les crochets angulaires? Quelqu'un peut-il m'aider avec le code?
Comment utiliser l'expression régulière C # pour remplacer / supprimer toutes les balises HTML, y compris les crochets angulaires? Quelqu'un peut-il m'aider avec le code?
Réponses:
Comme souvent indiqué précédemment, vous ne devez pas utiliser d'expressions régulières pour traiter des documents XML ou HTML. Ils ne fonctionnent pas très bien avec les documents HTML et XML, car il n'y a aucun moyen d'exprimer des structures imbriquées de manière générale.
Vous pouvez 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 chevrons) où cela ne fonctionnera pas comme prévu.
La bonne réponse est de ne pas faire cela, utilisez le HTML Agility Pack .
Modifié pour ajouter:
Pour voler sans vergogne le commentaire ci-dessous de jesse, et pour éviter d'être accusé de ne pas avoir répondu correctement à la question après tout ce temps, voici un extrait de code simple et fiable utilisant le HTML Agility Pack qui fonctionne avec les morceaux de HTML capricieux même les plus imparfaitement formés:
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 du HTML, car le HTML ne peut pas être analysé correctement sans une prise en compte du contexte qui est très difficile à fournir même dans un moteur de regex non traditionnel. Vous pouvez y arriver partiellement avec un RegEx, mais vous devrez effectuer des vérifications manuelles.
Html Agility Pack peut vous fournir une solution robuste qui réduira le besoin 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 apporter principalement ce que vous voulez la plupart du temps, mais elle échouera dans des cas très courants. Si vous pouvez trouver un analyseur meilleur / plus rapide que HTML Agility Pack, allez-y, mais veuillez ne pas soumettre le monde à un piratage HTML plus cassé.
La question est trop large pour recevoir une réponse définitive. Parlez-vous de la suppression de toutes les balises d'un document HTML réel, comme une page Web? Si tel est le cas, vous devrez:
C'est juste par dessus ma tête - je suis sûr qu'il y a plus. Une fois que vous avez fait tout cela, vous vous retrouverez avec des mots, des phrases et des paragraphes exécutés ensemble à certains endroits, et de gros morceaux d'espaces inutiles dans d'autres.
Mais, en supposant que vous travaillez avec juste un fragment et que vous puissiez simplement supprimer toutes les balises, voici l'expression régulière que j'utiliserais:
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
Faire correspondre les chaînes entre guillemets simples et doubles dans leurs propres alternatives suffit pour résoudre le problème des crochets angulaires dans les valeurs d'attribut. Je ne vois aucun besoin de faire correspondre explicitement les noms d'attributs et d'autres éléments à l'intérieur de la balise, comme le fait l'expression régulière dans la réponse de Ryan; la première alternative gère tout cela.
Au cas où vous vous poseriez des questions sur ces (?>...)
constructions, ce sont des groupes atomiques . Ils rendent le regex un peu plus efficace, mais plus important encore, ils empêchent le retour en arrière incontrôlé, ce à quoi vous devez toujours faire attention lorsque vous mélangez l'alternance et les quantificateurs imbriqués comme je l'ai fait. Je ne pense pas vraiment que ce serait un problème ici, mais je sais que si je ne le mentionne pas, quelqu'un d'autre le fera. ;-)
Cette expression régulière n'est pas parfaite, bien sûr, mais elle est probablement aussi bonne que vous en aurez jamais besoin.
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
@JasonTrue a raison, que la suppression des balises HTML ne doit pas être effectuée via 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;
}
Je voudrais faire écho à la réponse de Jason bien que parfois vous ayez besoin d'analyser naïvement du HTML et d'extraire le contenu du texte.
J'avais besoin de faire cela avec du Html qui avait été créé par un éditeur de texte riche, toujours amusant et amusant.
Dans ce cas, vous devrez peut-être supprimer le contenu de certaines balises ainsi que les balises elles-mêmes.
Dans mon cas, et des balises ont été jetées dans ce mélange. Certains peuvent trouver mon implémentation (très légèrement) moins naïve un point de départ utile.
/// <summary>
/// Removes all html tags from string and leaves only plain text
/// Removes content of <xml></xml> and <style></style> tags as aim to get text content not markup /meta data.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string HtmlStrip(this string input)
{
input = Regex.Replace(input, "<style>(.|\n)*?</style>",string.Empty);
input = Regex.Replace(input, @"<xml>(.|\n)*?</xml>", string.Empty); // remove all <xml></xml> tags and anything inbetween.
return Regex.Replace(input, @"<(.|\n)*?>", string.Empty); // remove any tags but not there content "<p>bob<span> johnson</span></p>" becomes "bob johnson"
}
<xml>.*(?!</xml>)</xml>
avec le RegexOptions.SingleLine
modificateur pour les deux premiers et <[^>]*>
pour le dernier. Les premiers peuvent également être combinés par une alternance capturée dans le premier nom de balise et des renvois à celui-ci dans l'anticipation négative et la balise finale.
essayez la méthode d'expression régulière à cette URL: http://www.dotnetperls.com/remove-html-tags
/// <summary>
/// Remove HTML from string with Regex.
/// </summary>
public static string StripTagsRegex(string source)
{
return Regex.Replace(source, "<.*?>", string.Empty);
}
/// <summary>
/// Compiled regular expression for performance.
/// </summary>
static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);
/// <summary>
/// Remove HTML from string with compiled Regex.
/// </summary>
public static string StripTagsRegexCompiled(string source)
{
return _htmlRegex.Replace(source, string.Empty);
}
Utilisez cette méthode pour supprimer les balises:
public string From_To(string text, string from, string to)
{
if (text == null)
return null;
string pattern = @"" + from + ".*?" + to;
Regex rx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
MatchCollection matches = rx.Matches(text);
return matches.Count <= 0 ? text : matches.Cast<Match>().Where(match => !string.IsNullOrEmpty(match.Value)).Aggregate(text, (current, match) => current.Replace(match.Value, ""));
}