regulares - expresión regular para extraer texto de HTML
probar expresiones regulares (12)
Me gustaría extraer de una página HTML general, todo el texto (visualizado o no).
Me gustaría eliminar
- cualquier etiqueta HTML
- Cualquier javascript
- Cualquier estilo CSS
¿Hay una expresión regular (una o más) que logre eso?
Contemplar hacer esto con expresiones regulares es desalentador. ¿Has considerado XSLT? La expresión XPath para extraer todos los nodos de texto en un documento XHTML, menos el contenido de script y estilo, sería:
//body//text()[not(ancestor::script)][not(ancestor::style)]
Creo que puedes hacer
document.body.innerText
Que devolverá el contenido de todos los nodos de texto en el documento, visible o no.
[edit (olliej): suspiro no importa, esto solo funciona en Safari e IE, y no me molesta descargar un firefox todas las noches para ver si existe en el maletero: - /]
Eliminar javascript y CSS:
<(script|style).*?<//1>
Eliminar etiquetas
<.*?>
Si usas PHP, prueba Simple HTML DOM, disponible en SourceForge.
De lo contrario, Google html2text, y encontrarás una variedad de implementaciones para diferentes idiomas que básicamente usan una serie de expresiones regulares para absorber todo el marcado. Tenga cuidado aquí, porque a veces se pueden dejar etiquetas sin terminaciones, así como caracteres especiales como & (que es & amp;).
Además, ten cuidado con los comentarios y Javascript, ya que he descubierto que es particularmente molesto tratar con expresiones regulares, y por qué generalmente prefiero dejar que un analizador gratuito haga todo el trabajo por mí.
Usando la sintaxis de Perl para definir las expresiones regulares, un inicio podría ser:
!<body.*?>(.*)</body>!smi
Luego, aplicando lo siguiente, reemplaza al resultado de ese grupo:
!<script.*?</script>!!smi
!<[^>]+/[ /t]*>!!smi
!</?([a-z]+).*?>!!smi
/<!--.*?-->//smi
Esto, por supuesto, no formateará las cosas como un archivo de texto, pero borrará todo el HTML (en su mayoría, hay algunos casos en los que podría no funcionar del todo bien). Sin embargo, una mejor idea es usar un analizador XML en cualquier idioma que esté usando para analizar correctamente el HTML y extraer el texto de eso.
Tampoco estoy seguro de que esta página pueda ayudar.
Realmente no se puede analizar HTML con expresiones regulares. Es muy complejo. RE no manejará <![CDATA[
secciones correctamente en absoluto. Además, algunos tipos de elementos HTML comunes como <text>
funcionarán en un navegador como texto adecuado, pero podrían confundir a un RE ingenuo.
Serás más feliz y más exitoso con un analizador de HTML adecuado. Los usuarios de Python suelen usar algo como Beautiful Soup para analizar HTML y quitar etiquetas y scripts.
Además, los navegadores, por diseño, toleran HTML mal formado. Por lo tanto, a menudo se encontrará tratando de analizar HTML que es claramente incorrecto, pero que funciona bien en un navegador.
Es posible que pueda analizar HTML incorrecto con RE. Todo lo que requiere es paciencia y trabajo duro. Pero a menudo es más simple usar el analizador de otra persona.
La forma más simple para HTML simple (ejemplo en Python):
text = "<p>This is my> <strong>example</strong>HTML,<br /> containing tags</p>"
import re
" ".join([t.strip() for t in re.findall(r"<[^>]+>|[^<]+",text) if not ''<'' in t])
Devuelve esto:
''This is my> example HTML, containing tags''
Aquí hay una función para eliminar incluso las etiquetas html más complejas.
function strip_html_tags( $text )
{
$text = preg_replace(
array(
// Remove invisible content
''@<head[^>]*?>.*?</head>@siu'',
''@<style[^>]*?>.*?</style>@siu'',
''@<script[^>]*?.*?</script>@siu'',
''@<object[^>]*?.*?</object>@siu'',
''@<embed[^>]*?.*?</embed>@siu'',
''@<applet[^>]*?.*?</applet>@siu'',
''@<noframes[^>]*?.*?</noframes>@siu'',
''@<noscript[^>]*?.*?</noscript>@siu'',
''@<noembed[^>]*?.*?</noembed>@siu'',
// Add line breaks before & after blocks
''@<((br)|(hr))@iu'',
''@</?((address)|(blockquote)|(center)|(del))@iu'',
''@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu'',
''@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu'',
''@</?((table)|(th)|(td)|(caption))@iu'',
''@</?((form)|(button)|(fieldset)|(legend)|(input))@iu'',
''@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu'',
''@</?((frameset)|(frame)|(iframe))@iu'',
),
array(
'' '', '' '', '' '', '' '', '' '', '' '', '' '', '' '', '' '',
"/n/$0", "/n/$0", "/n/$0", "/n/$0", "/n/$0", "/n/$0",
"/n/$0", "/n/$0",
),
$text );
// Remove all remaining tags and comments and return.
return strip_tags( $text );
}
¿No puedes usar el control WebBrowser disponible con C #?
System.Windows.Forms.WebBrowser wc = new System.Windows.Forms.WebBrowser();
wc.DocumentText = "<html><body>blah blah<b>foo</b></body></html>";
System.Windows.Forms.HtmlDocument h = wc.Document;
Console.WriteLine(h.Body.InnerText);
string decode = System.Web.HttpUtility.HtmlDecode(your_htmlfile.html);
Regex objRegExp = new Regex("<(.|/n)+?>");
string replace = objRegExp.Replace(g, "");
replace = replace.Replace(k, string.Empty);
replace.Trim("/t/r/n ".ToCharArray());
then take a label and do "label.text=replace;" see on label out put
.
Se necesitaba una solución de expresiones regulares ( en php ) que devolviera el texto simple igual de bien (o mejor que) PHPSimpleDOM, solo que mucho más rápido. Aquí está la solución que se me ocurrió:
function plaintext($html)
{
// remove comments and any content found in the the comment area (strip_tags only removes the actual tags).
$plaintext = preg_replace(''#<!--.*?-->#s'', '''', $html);
// put a space between list items (strip_tags just removes the tags).
$plaintext = preg_replace(''#</li>#'', '' </li>'', $plaintext);
// remove all script and style tags
$plaintext = preg_replace(''#<(script|style)/b[^>]*>(.*?)</(script|style)>#is'', "", $plaintext);
// remove br tags (missed by strip_tags)
$plaintext = preg_replace("#<br[^>]*?>#", " ", $plaintext);
// remove all remaining html
$plaintext = strip_tags($plaintext);
return $plaintext;
}
Cuando probé esto en algunos sitios complicados (los foros parecen contener algunos de los html más difíciles de analizar), este método arrojó el mismo resultado que el texto simple PHPSimpleDOM, solo que mucho, mucho más rápido. También manejaba los elementos de la lista (etiquetas li) correctamente, donde PHPSimpleDOM no lo hacía.
En cuanto a la velocidad:
- SimpleDom: 0.03248 seg.
- RegEx: 0.00087 seg.
¡37 veces más rápido!