¿Cómo uso la expresión regular de C # para reemplazar / eliminar todas las etiquetas HTML, incluidos los corchetes angulares? ¿Puede alguien ayudarme con el código?
¿Cómo uso la expresión regular de C # para reemplazar / eliminar todas las etiquetas HTML, incluidos los corchetes angulares? ¿Puede alguien ayudarme con el código?
Respuestas:
Como se indicó anteriormente, no debe usar expresiones regulares para procesar documentos XML o HTML. No funcionan muy bien con documentos HTML y XML, porque no hay forma de expresar estructuras anidadas de manera general.
Podrías usar lo siguiente.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Esto funcionará para la mayoría de los casos, pero habrá casos (por ejemplo, CDATA que contienen paréntesis angulares) en los que esto no funcionará como se esperaba.
La respuesta correcta es no hacer eso, use el paquete de agilidad HTML .
Editado para agregar:
Para robar descaradamente el comentario a continuación de jesse, y para evitar ser acusado de responder inadecuadamente la pregunta después de todo este tiempo, aquí hay un fragmento simple y confiable que usa el paquete de agilidad HTML que funciona incluso con los fragmentos de HTML caprichosos más imperfectamente formados:
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());
Hay muy pocos casos defendibles para usar una expresión regular para analizar HTML, ya que HTML no se puede analizar correctamente sin una conciencia de contexto que es muy dolorosa de proporcionar incluso en un motor de expresiones regulares no tradicionales. Puede llegar hasta allí con un RegEx, pero deberá hacer verificaciones manuales.
Html Agility Pack puede proporcionarle una solución sólida que reducirá la necesidad de corregir manualmente las aberraciones que pueden resultar del tratamiento ingenuo de HTML como una gramática libre de contexto.
Una expresión regular puede obtener la mayoría de las veces lo que desea, pero fallará en casos muy comunes. Si puede encontrar un analizador mejor / más rápido que HTML Agility Pack, hágalo, pero no someta al mundo a hackers de HTML más rotos.
La pregunta es demasiado amplia para ser respondida definitivamente. ¿Estás hablando de eliminar todas las etiquetas de un documento HTML del mundo real, como una página web? Si es así, tendrías que:
Eso está justo en la parte superior de mi cabeza: estoy seguro de que hay más. Una vez que hayas hecho todo eso, terminarás con palabras, oraciones y párrafos juntos en algunos lugares, y grandes pedazos de espacios en blanco inútiles en otros.
Pero, suponiendo que esté trabajando con solo un fragmento y pueda salirse con la simple eliminación de todas las etiquetas, aquí está la expresión regular que usaría:
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
Coincidir cadenas de comillas simples y dobles en sus propias alternativas es suficiente para tratar el problema de los corchetes angulares en los valores de los atributos. No veo ninguna necesidad de hacer coincidir explícitamente los nombres de los atributos y otras cosas dentro de la etiqueta, como lo hace la expresión regular en la respuesta de Ryan; La primera alternativa maneja todo eso.
En caso de que te estés preguntando acerca de esas (?>...)
construcciones, son grupos atómicos . Hacen que la expresión regular sea un poco más eficiente, pero lo que es más importante, evitan el retroceso descontrolado, que es algo que siempre debes tener en cuenta cuando mezclas alternancia y cuantificadores anidados como lo he hecho. Realmente no creo que eso sea un problema aquí, pero sé que si no lo menciono, alguien más lo hará. ;-)
Esta expresión regular no es perfecta, por supuesto, pero probablemente sea tan buena como la que alguna vez necesitarás.
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
@JasonTrue es correcto, que la eliminación de etiquetas HTML no debe hacerse a través de expresiones regulares.
Es bastante simple quitar las etiquetas HTML usando HtmlAgilityPack:
public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}
Me gustaría hacer eco de la respuesta de Jason, aunque a veces es necesario analizar ingenuamente algunos HTML y extraer el contenido del texto.
Necesitaba hacer esto con un poco de HTML creado por un editor de texto enriquecido, siempre divertido y con juegos.
En este caso, es posible que deba eliminar el contenido de algunas etiquetas, así como solo las etiquetas mismas.
En mi caso y las etiquetas fueron arrojadas a esta mezcla. Alguien puede encontrar mi implementación (muy ligeramente) menos ingenua como un punto de partida útil.
/// <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>
con el RegexOptions.SingleLine
modificador para los dos primeros y <[^>]*>
para el último. Los primeros también se pueden combinar mediante una alternancia capturada en el primer nombre de etiqueta y referencias posteriores a ella en la etiqueta de búsqueda negativa y final.
pruebe el método de expresión regular en esta 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);
}
Añadir .+?
en <[^>]*>
y tratar esta expresión regular (base en esto ):
<[^>].+?>
Use este método para eliminar etiquetas:
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, ""));
}