Question

Je voudrais extraire d'une page HTML générale tout le texte (affiché ou non).

Je souhaite supprimer

  • les balises HTML
  • Tout javascript
  • Tous les styles CSS

Existe-t-il une expression régulière (une ou plusieurs) permettant d’atteindre cet objectif?

Était-ce utile?

La solution

Vous ne pouvez pas vraiment analyser HTML avec des expressions régulières. C'est trop complexe. Les RE ne gèreront pas <![CDATA[ les sections correctement. De plus, certains types de choses HTML courantes telles que &lt;text> fonctionneront dans un navigateur en tant que texte approprié, mais risquent de dérouter une RE naïve.

Vous serez plus heureux et aurez plus de succès avec un analyseur HTML approprié. Les gens de Python utilisent souvent quelque chose Beautiful Soup pour analyser le code HTML et effacer les balises et les scripts.

De plus, les navigateurs, de par leur conception, tolèrent le code HTML mal formé. Ainsi, vous vous retrouverez souvent en train d’essayer d’analyser du HTML qui est clairement incorrect, mais qui fonctionne bien dans un navigateur.

Vous pourrez peut-être analyser le mauvais HTML avec les RE. Il suffit de patience et de travail acharné. Mais il est souvent plus simple d'utiliser l'analyseur de quelqu'un d'autre.

Autres conseils

Supprimer javascript et CSS:

<(script|style).*?</\1>

Supprimer les tags

<.*?>

Besoin d'une solution regex ( en php ) qui renvoie le texte brut aussi bien (ou mieux que) PHPSimpleDOM, mais beaucoup plus rapidement. Voici la solution que j'ai proposée:

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;
}

Lorsque j'ai testé cela sur des sites complexes (les forums semblent contenir certains des codes html les plus difficiles à analyser), cette méthode a renvoyé le même résultat que le texte en clair PHPSimpleDOM, mais beaucoup, beaucoup plus rapidement. Il a également géré correctement les éléments de la liste (balises li), contrairement à PHPSimpleDOM.

En ce qui concerne la vitesse:

  • SimpleDom: 0.03248 sec.
  • RegEx: 0,00087 sec.

37 fois plus rapide!

Il est décourageant d’envisager de faire cela avec des expressions régulières. Avez-vous envisagé XSLT? L'expression XPath permettant d'extraire tous les nœuds de texte d'un document XHTML, moins le script & Amp; contenu de style, serait:

//body//text()[not(ancestor::script)][not(ancestor::style)]

En utilisant la syntaxe perl pour définir les expressions rationnelles, vous pouvez commencer par:

!<body.*?>(.*)</body>!smi

Appliquez ensuite le remplacement suivant au résultat de ce groupe:

!<script.*?</script>!!smi
!<[^>]+/[ \t]*>!!smi
!</?([a-z]+).*?>!!smi
/<!--.*?-->//smi

Bien entendu, cela ne formatera pas les choses comme un fichier texte, mais cela supprimera tout le code HTML (la plupart du temps, il pourrait ne pas fonctionner correctement). Cependant, une meilleure idée consiste à utiliser un analyseur XML dans le langage que vous utilisez pour analyser correctement le code HTML et en extraire le texte.

La manière la plus simple d'utiliser du HTML simple (exemple 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])

Renvoie ceci:

'This is my> example HTML, containing tags'

Voici une fonction permettant de supprimer même les balises HTML les plus complexes.

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 );
    }

Si vous utilisez PHP, essayez Simple HTML DOM, disponible sur SourceForge.

Sinon, dans Google html2text, vous trouverez une variété d'implémentations pour différents langages qui utilisent essentiellement une série d'expressions régulières pour aspirer tout le balisage. Soyez prudent ici, car des étiquettes sans fin peuvent parfois rester, ainsi que des caractères spéciaux tels que & Amp; (qui est & amp; amp;).

Faites également attention aux commentaires et au Javascript, car j’ai trouvé particulièrement agaçant les expressions régulières et la raison pour laquelle je préfère simplement laisser un analyseur gratuit faire tout le travail à ma place.

Ne pensez pas que cette page pourrait vous aider.

Ne pouvez-vous pas simplement utiliser le contrôle WebBrowser disponible en 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

.

Je crois que vous pouvez simplement faire

document.body.innerText

Qui renverra le contenu de tous les nœuds de texte du document, visible ou non.

[edit (olliej): soupir tant pis, cela ne fonctionne que dans Safari et IE, et je ne peux pas être dérangé par le téléchargement d’un firefox tous les soirs pour voir s’il existe dans le coffre: - /]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top