web-dev-qa-db-fra.com

Supprimer les balises HTML en Java

Existe-t-il une bibliothèque Java qui fournit une méthode pour supprimer toutes les balises HTML d'une chaîne? Je recherche quelque chose d'équivalent à la fonction strip_tags en PHP. 

Je sais que je peux utiliser une expression rationnelle comme décrit dans cette question de Stackoverflow , mais j’étais curieux de savoir s’il existait déjà une méthode stripTags() flottant dans la bibliothèque Apache Commons.

39
Todd

Après avoir ouvert cette question pendant près d'une semaine, je peux affirmer avec certitude qu'il n'existe aucune méthode disponible dans les bibliothèques Java API ou Apache qui supprime les balises HTML d'une chaîne. Vous devrez soit utiliser un analyseur HTML, comme décrit dans les réponses précédentes, ou écrire une expression régulière simple pour supprimer les balises.

11
Todd

Utilisez JSoup , il est bien documenté, disponible sur Maven et, après une journée passée dans plusieurs bibliothèques, pour moi, c’est le meilleur que je puisse imaginer. Mon opinion personnelle est qu’un tel travail, l’analyse html en texte brut, devrait être possible dans une ligne de code -> sinon la bibliothèque a échoué en quelque sorte ... juste en disant ^^ Donc voilà, le one-liner de JSoup - dans Markdown4J, quelque chose comme ça n’est pas possible , dans Markdownj aussi, dans htmlCleaner, c’est douloureux avec environ 50 lignes de code ...

String plain = new HtmlToPlainText().getPlainText(Jsoup.parse(html));

Et ce que vous avez est du texte brut (pas seulement le code source HTML en tant que chaîne, comme dans les autres bibliothèques lol) -> il fait vraiment du bon travail à cet égard. C'est plus ou moins la même qualité que Markdownify pour PHP ....

33
jebbie

Quoi que vous fassiez, assurez-vous de normaliser les données avant de commencer à essayer de supprimer les balises. J'ai récemment assisté à un atelier sur la sécurité des applications Web qui couvrait l'évasion des filtres XSS. On pourrait normalement penser que la recherche de < ou &lt; ou de son équivalent hexadécimal serait suffisante. J'ai été époustouflé après avoir vu une diapositive présentant 70 façons dont < peut être codé pour battre les filtres.

Mettre à jour:

Vous trouverez ci-dessous la présentation à laquelle vous faites référence. Voir la diapositive 26 pour connaître les 70 méthodes de codage <.

Filtre Evasion: Houdini sur le fil

29
Jason Fritcher

C'est ce que j'ai trouvé sur google dessus. Pour moi cela a bien fonctionné.

String noHTMLString = htmlString.replaceAll("\\<.*?\\>", "");
29

Il y en a peut-être, mais le plus robuste est d'utiliser un analyseur HTML réel. Il existe un ici , et s’il est assez bien formé, vous pouvez également utiliser SAX ou un autre analyseur XML.

11
Charlie Martin

Lorsque vous utilisez Jsoup, c'est encore plus facile que ce qui est décrit dans les réponses ci-dessus:

String html = "bla <b>hehe</b> <br> this is awesome simple";

String text = Jsoup.parse(html).text();

J'ai utilisé nekoHtml pour le faire. Il peut supprimer toutes les balises, mais il peut également conserver ou supprimer un sous-ensemble de balises.

6
Solomon Duskis

Je sais que cette question est assez ancienne, mais je la recherchais aussi et il semble que trouver une solution simple et efficace en Java ne semble pas encore facile.

Aujourd'hui, je suis tombé sur cette petite fonction lib. Il tente en réalité d'imiter la fonction php strip_tags.

http://jmelo.lyncode.com/Java-strip_tags-php-function/

Cela fonctionne comme ceci (copié de leur site):

    import static com.lyncode.jtwig.functions.util.HtmlUtils.stripTags;

    public class StripTagsExample {
      public static void main(String... args) {
        String result = stripTags("<!-- <a href='test'></a>--><a>Test</a>", "");
        // Produced result: Test
      }
    }
5
michaeldd

Bonjour, je sais que ce fil est ancien, mais il est toujours sorti en tête sur Google et je cherchais une solution rapide au même problème. N'ayant rien trouvé d'utile, j'ai donc proposé cet extrait de code. J'espère que cela aidera quelqu'un. Il boucle simplement sur la chaîne et saute toutes les balises. Simple et simple.

boolean intag = false;
String inp = "<H1>Some <b>HTML</b> <span style=blablabla>text</span>";
String outp = "";

for (int i=0; i < inp.length(); ++i)
{
    if (!intag && inp.charAt(i) == '<')
        {
            intag = true;
            continue;
        }
        if (intag && inp.charAt(i) == '>')
        {
            intag = false;
            continue;
        }
        if (!intag)
        {
            outp = outp + inp.charAt(i);
        }
}   
return outp;
3
Lou

Avec une approche purement itérative et sans regex:

public String stripTags(final String html) {

    final StringBuilder sbText = new StringBuilder(1000);
    final StringBuilder sbHtml = new StringBuilder(1000);

    boolean isText = true;

    for (char ch : html.toCharArray()) {
        if (isText) { // outside html
            if (ch != '<') {
                sbText.append(ch);
                continue;
            } else {   // switch mode             
                isText = false;      
                sbHtml.append(ch); 
                continue;
            }
        }else { // inside html
            if (ch != '>') {
                sbHtml.append(ch);
                continue;
            } else {      // switch mode    
                isText = true;     
                sbHtml.append(ch); 
                continue;
            }
        }
    }

    return sbText.toString();
}
3
Mitja Gustin

En raison de l'abréviation (chaîne de troncature) du fragment HTML, j'ai également eu le problème des balises HTML non fermées que regex ne peut pas détecter .

Lorem ipsum dolor sit amet, <b>consectetur</b> adipiscing elit. <a href="abc"

Donc, en référence aux 2 meilleures réponses (JSoup et regex), j'ai préféré une solution utilisant JSoup:

Jsoup.parse(html).text()
1
Fabio Formosa

Wicket utilise la méthode suivante pour sortir du code HTML, situé dans: org.Apache.wicket.util.string.Strings

public static CharSequence escapeMarkup(final String s, final boolean escapeSpaces,
    final boolean convertToHtmlUnicodeEscapes)
{
    if (s == null)
    {
        return null;
    }
    else
    {
        int len = s.length();
        final AppendingStringBuffer buffer = new AppendingStringBuffer((int)(len * 1.1));

        for (int i = 0; i < len; i++)
        {
            final char c = s.charAt(i);

            switch (c)
            {
                case '\t' :
                    if (escapeSpaces)
                    {
                        // Assumption is four space tabs (sorry, but that's
                        // just how it is!)
                        buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;");
                    }
                    else
                    {
                        buffer.append(c);
                    }
                    break;

                case ' ' :
                    if (escapeSpaces)
                    {
                        buffer.append("&nbsp;");
                    }
                    else
                    {
                        buffer.append(c);
                    }
                    break;

                case '<' :
                    buffer.append("&lt;");
                    break;

                case '>' :
                    buffer.append("&gt;");
                    break;

                case '&' :

                    buffer.append("&amp;");
                    break;

                case '"' :
                    buffer.append("&quot;");
                    break;

                case '\'' :
                    buffer.append("&#039;");
                    break;

                default :

                    if (convertToHtmlUnicodeEscapes)
                    {
                        int ci = 0xffff & c;
                        if (ci < 160)
                        {
                            // nothing special only 7 Bit
                            buffer.append(c);
                        }
                        else
                        {
                            // Not 7 Bit use the unicode system
                            buffer.append("&#");
                            buffer.append(new Integer(ci).toString());
                            buffer.append(';');
                        }
                    }
                    else
                    {
                        buffer.append(c);
                    }

                    break;
            }
        }

        return buffer;
    }
}
0
Arthur
public static String stripTags(String str) {
    int startPosition = str.indexOf('<');
    int endPosition;
    while (startPosition != -1) {
        endPosition = str.indexOf('>', startPosition);
        str = str.substring(0, startPosition) + (endPosition != -1 ? str.substring(endPosition + 1) : "");
        startPosition = str.indexOf('<');
    }
    return str;
}
0
AHHP