tutorial - regular expressions in c#
Uso de expresiones regulares C#para eliminar etiquetas HTML (10)
@JasonTrue es correcto, que pelar etiquetas HTML no debería hacerse a través de expresiones regulares.
Es bastante simple quitar etiquetas HTML usando HtmlAgilityPack:
public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}
¿Cómo uso la expresión regular C # para reemplazar / eliminar todas las etiquetas HTML, incluidos los corchetes angulares? ¿Alguien puede ayudarme con el código?
Añadir .+?
en <[^>]*>
y prueba esta expresión regular (base en this ):
<[^>].+?>
Como se mencionó 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.
Puedes 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 con paréntesis angulares) en los que esto no funcionará como se esperaba.
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:
- elimine la declaración <! DOCTYPE o <? xml prolog si existen
- eliminar todos los comentarios de SGML
- eliminar todo el elemento HEAD
- eliminar todos los elementos SCRIPT y STYLE
- hacer Grabthar-sabe-qué con los elementos FORM y TABLE
- eliminar las etiquetas restantes
- elimine las secuencias <! [CDATA [y]]> de las secciones CDATA, pero deje su contenido solo
Eso está fuera de mi cabeza, estoy seguro de que hay más. Una vez que haya hecho todo eso, terminará con palabras, oraciones y párrafos que se ejecutan juntos en algunos lugares, y grandes espacios inútiles en otros.
Pero, asumiendo que estás trabajando con solo un fragmento y puedes salirte con la suya simplemente eliminando todas las etiquetas, aquí está la expresión regular que usaría:
@"(?></?/w+)(?>(?:[^>''""]+|''[^'']*''|""[^""]*"")*)>"
La coincidencia de 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 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 sobre esos constructos (?>...)
, son grupos atómicos . Hacen que la expresión regular sea un poco más eficiente, pero lo más importante es que evitan el retroceso fugitivo, que es algo que siempre se debe tener cuidado cuando se mezclan la alternancia y los cuantificadores anidados como lo hice. Realmente no creo que 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 es probable que sea tan buena como puedas necesitar.
La respuesta correcta es no hacer eso, use el HTML Agility Pack .
Editado para agregar:
Para descaradamente robar el comentario de abajo de jesse, y para evitar ser acusado de responder incorrectamente la pregunta después de todo este tiempo, aquí hay un fragmento simple y confiable que usa el HTML Agility Pack que funciona con la mayoría de los bits de HTML caprichosos y de forma imperfecta:
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 participar de manera parcial con un RegEx, pero deberá realizar verificaciones manuales.
Html Agility Pack puede proporcionarle una solución robusta que reducirá la necesidad de reparar manualmente las aberraciones que pueden derivarse de tratar ingenuamente HTML como una gramática libre de contexto.
Una expresión regular puede obtener principalmente lo que desea la mayoría del tiempo, pero fallará en casos muy comunes. Si puedes encontrar un analizador mejor / más rápido que HTML Agility Pack, hazlo, pero no sometas al mundo a más hacks de HTML rotos.
Me gustaría hacerme 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 algunos Html que habían sido creados por un editor de texto enriquecido, siempre divertidos y juegos.
En este caso, es posible que deba eliminar el contenido de algunas etiquetas, así como las etiquetas mismas.
En mi caso, las etiquetas fueron arrojadas a esta mezcla. Alguien puede encontrar que mi implementación (muy ligeramente) menos ingenua es 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"
}
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, ""));
}
prueba 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);
}
utilizar esta..
@"(?></?/w+)(?>(?:[^>''""]+|''[^'']*''|""[^""]*"")*)>"
Regex regex = new Regex(@"</?/w+((/s+/w+(/s*=/s*(?:"".*?""|''.*?''|[^''"">/s]+))?)+/s*|/s*)/?>", RegexOptions.Singleline);