468 votes

Supprimer les balises HTML d'une chaîne

Existe-t-il un bon moyen de supprimer le HTML d'une chaîne Java ? Une simple expression rationnelle comme

replaceAll("\\<.*?>", "") 

fonctionnera, mais des choses comme &amp; sera converti correctement et les éléments nonHTML situés entre les deux crochets seront supprimés (c'est-à-dire que l'élément .*? dans la regex disparaîtra).

3 votes

Utilisez-le avec le guide suivant : compilez 'org.jsoup:jsoup:1.9.2'.

1 votes

0 votes

632voto

BalusC Points 498232

Utiliser un analyseur HTML au lieu d'une regex. C'est très simple avec Jsoup .

public static String html2text(String html) {
    return Jsoup.parse(html).text();
}

Jsoup aussi soutient supprimer les balises HTML en les comparant à une liste blanche personnalisable, ce qui est très utile si vous souhaitez autoriser uniquement les balises suivantes, par exemple <b> , <i> et <u> .

Voir aussi :

18 votes

Jsoup est sympa, mais j'ai rencontré quelques inconvénients avec elle. Je l'utilise pour me débarrasser des XSS, c'est-à-dire que j'attends une entrée en texte brut, mais une personne malveillante pourrait essayer de m'envoyer du HTML. En utilisant Jsoup, je peux supprimer tout le HTML mais, malheureusement, il réduit également de nombreux espaces à un seul et supprime les ruptures de liens ( \n personnages)

7 votes

@Ridcully : pour cela, il faut utiliser Jsoup#clean() à la place.

3 votes

L'utilisation de clean() provoquera toujours des espaces supplémentaires et des \n les caractères à supprimer. ex : Jsoup.clean("a \n b", Whitelist.none()) renvoie "a b".

295voto

Ken Goodridge Points 1736

Si vous écrivez pour Android vous pouvez faire ça...

android.text.HtmlCompat.fromHtml(instruction, HtmlCompat.FROM_HTML_MODE_LEGACY).toString()

12 votes

Une astuce géniale :) Si vous affichez le texte dans un TextView, vous pouvez laisser tomber le .toString() pour préserver le formatage, également.

1 votes

@Branky Ce n'est pas le cas, j'ai essayé... la réponse acceptée fonctionne comme un charme.

0 votes

Il fonctionne très bien. Toutes les balises html ont été supprimées de la chaîne.

92voto

Chris Marasti-Georg Points 17023

Si l'utilisateur saisit <b>hey!</b> voulez-vous afficher <b>hey!</b> ou hey! ? Si c'est la première option, échappez les less-thans et codez les esperluettes en html (et éventuellement les guillemets) et tout ira bien. Une modification de votre code pour implémenter la seconde option serait :

replaceAll("\\<[^>]*>","")

mais vous rencontrerez des problèmes si l'utilisateur saisit quelque chose de malformé, comme <bhey!</b> .

Vous pouvez également consulter JTidy qui analysera les entrées html "sales", et devrait vous donner un moyen de supprimer les balises, en conservant le texte.

Le problème quand on essaie de dépouiller le html est que les navigateurs ont des analyseurs très indulgents, plus indulgents que n'importe quelle bibliothèque que vous pouvez trouver, donc même si vous faites de votre mieux pour dépouiller toutes les balises (en utilisant la méthode de remplacement ci-dessus, une bibliothèque DOM, ou JTidy), vous aurez toujours vous devez vous assurer de coder tous les caractères spéciaux HTML restants pour garantir la sécurité de votre sortie.

1 votes

Vous rencontrez également des problèmes, s'il y a un signe < ou > non souligné à l'intérieur du contenu du nœud html. <span>Mon âge est < beaucoup de texte > puis votre âge</span>. Je pense que la seule façon de le faire à 100% est via une interface DOM XML (comme SAX ou similaire), pour utiliser node.getText().

30voto

RealHowTo Points 13117

Une autre façon est d'utiliser javax.swing.text.html.HTMLEditorKit pour extraire le texte.

import java.io.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;

public class Html2Text extends HTMLEditorKit.ParserCallback {
    StringBuffer s;

    public Html2Text() {
    }

    public void parse(Reader in) throws IOException {
        s = new StringBuffer();
        ParserDelegator delegator = new ParserDelegator();
        // the third parameter is TRUE to ignore charset directive
        delegator.parse(in, this, Boolean.TRUE);
    }

    public void handleText(char[] text, int pos) {
        s.append(text);
    }

    public String getText() {
        return s.toString();
    }

    public static void main(String[] args) {
        try {
            // the HTML to convert
            FileReader in = new FileReader("java-new.html");
            Html2Text parser = new Html2Text();
            parser.parse(in);
            in.close();
            System.out.println(parser.getText());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

réf : Supprimer les balises HTML d'un fichier pour n'extraire que le TEXTE

5 votes

Le résultat de "a < b ou b > c" est "a b ou b > c", ce qui semble malheureux.

1 votes

C'est ce qui a le mieux fonctionné pour moi. J'avais besoin de préserver les sauts de ligne. Je l'ai fait en ajoutant cette méthode simple à l'analyseur syntaxique : @Override public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { if (t == HTML.Tag.P || t = HTML.Tag.BR) { s.append(' \n ') ; } }

2 votes

Dfrankow : L'expression mathématique a < b ou b > c devrait être écrite en html comme ceci : a < b ou b > c

18voto

Josh Points 121

Il est également très simple d'utiliser Jéricho et vous pouvez conserver une partie du formatage (sauts de ligne et liens, par exemple).

    Source htmlSource = new Source(htmlText);
    Segment htmlSeg = new Segment(htmlSource, 0, htmlSource.length());
    Renderer htmlRend = new Renderer(htmlSeg);
    System.out.println(htmlRend.toString());

4 votes

Jericho a pu analyser <br>à un saut de ligne. Jsoup et HTMLEditorKit ne pouvaient pas le faire.

0 votes

Jericho est tout à fait capable de faire ce travail, il l'a beaucoup utilisé dans ses propres projets.

3 votes

Jericho a travaillé comme un charme. Merci pour cette suggestion. Une remarque : il n'est pas nécessaire de créer un segment de la chaîne entière. Source étend Segment, donc l'un ou l'autre fonctionne dans le constructeur du Renderer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X