Supprimer des balises HTML d'une chaîne

422

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

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

fonctionnera, mais des choses comme &amp;ne seront pas converties correctement et le non-HTML entre les deux crochets sera supprimé (c'est- .*?à- dire que dans l'expression régulière disparaîtra).

le maçon
la source
2
utilisez ceci avec le guide suivant: compilez 'org.jsoup: jsoup: 1.9.2'
VahidHoseini

Réponses:

572

Utilisez un analyseur HTML au lieu de regex. C'est très simple avec Jsoup .

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

Jsoup prend également en charge la suppression des balises HTML par rapport à une liste blanche personnalisable, ce qui est très utile si vous souhaitez autoriser uniquement, par exemple <b>, <i>et <u>.

Voir également:

BalusC
la source
18
Jsoup est sympa, mais j'ai rencontré quelques inconvénients avec. Je l'utilise pour me débarrasser de XSS, donc en gros je m'attends à une entrée en texte brut, mais une personne maléfique 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 et supprime les ruptures de liens (\ n caractères)
Ridcully
7
@Ridcully: pour cela, vous souhaitez utiliser à la Jsoup#clean()place.
BalusC
3
l'utilisation de clean () entraînera toujours la suppression des \ n espaces supplémentaires et des caractères. ex: Jsoup.clean ("a \ n b", Whitelist.none ()) renvoie "a b"
Keith
20
@Zeroows: cela échoue lamentablement <p>Lorem ipsum 1 < 3 dolor sit amet</p>. Encore une fois, HTML n'est pas un langage standard . Cela me dépasse complètement pourquoi tout le monde essaie de lancer des expressions rationnelles dessus pour analyser des parties d'intérêt au lieu d'utiliser un véritable analyseur.
BalusC
4
utiliser Jsoup.clean(unsafeString, "", Whitelist.none(), new OutputSettings().prettyPrint(false));pour préserver les sauts de ligne
Marc Johnen
275

Si vous écrivez pour Android, vous pouvez le faire ...

android.text.Html.fromHtml(instruction).toString()
Ken Goodridge
la source
12
Astuce génial. :) Si vous affichez le texte dans une TextView, vous pouvez également supprimer le .toString () pour conserver une certaine mise en forme.
Lorne Laliberte
1
@Branky Ce n'est pas que j'ai essayé ... la réponse acceptée fonctionne comme un charme
Maverick
Fonctionne très bien. Toutes les balises html ont été supprimées de la chaîne.
user3144836
1
C'est bien, mais les balises <img> sont remplacées par des choses bizarres. J'ai eu de petits carrés où il y avait une image
Bibaswann Bandyopadhyay
1
@BibaswannBandyopadhyay une autre réponse aide à se débarrasser de ces personnages
Vince
84

Si l'utilisateur entre <b>hey!</b>, voulez-vous afficher <b>hey!</b>ou hey!? Si c'est le premier, échappez à less-thans et html-encode esperluette (et éventuellement des guillemets) et tout va bien. Une modification de votre code pour implémenter la deuxième option serait:

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

mais vous rencontrerez des problèmes si l'utilisateur entre 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 tout en conservant le texte.

Le problème avec la suppression du code HTML est que les navigateurs ont des analyseurs très cléments, plus clément que n'importe quelle bibliothèque que vous pouvez trouver, donc même si vous faites de votre mieux pour supprimer toutes les balises (en utilisant la méthode replace ci-dessus, une bibliothèque DOM ou JTidy) , vous devrez toujours vous assurer d'encoder tous les caractères spéciaux HTML restants pour garantir la sécurité de votre sortie.

Chris Marasti-Georg
la source
1
Vous rencontrez également des problèmes, s'il y a un signe <ou> non échappé dans le contenu du nœud html. <span> Mon âge est <beaucoup de texte> puis votre âge </span>. Je pense que seulement 100% pour ce faire est via une interface DOM XML (comme SAX ou similaire), pour utiliser node.getText ().
Mitja Gustin
29

Une autre façon consiste à 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();
        }
    }
}

ref: Supprimer les balises HTML d'un fichier pour extraire uniquement le TEXTE

RealHowTo
la source
5
Le résultat de "a <b ou b> c" est "ab ou b> c", ce qui semble regrettable.
dfrankow
1
Cela a fonctionné le mieux pour moi. J'avais besoin de conserver les sauts de ligne. Je l'ai fait en ajoutant cette méthode simple à l'analyseur: @Override public void handleStartTag (HTML.Tag t, MutableAttributeSet a, int pos) {if (t == HTML.Tag.P || t == HTML.Tag.BR) {s.append ('\ n'); }}
MiguelMunoz
1
dfrankow: L'expression mathématique a <b ou b> c doit être écrite en html comme ceci: a & lt; b ou b & gt; c
MiguelMunoz
24

Je pense que la façon la plus simple de filtrer les balises html est:

private static final Pattern REMOVE_TAGS = Pattern.compile("<.+?>");

public static String removeTags(String string) {
    if (string == null || string.length() == 0) {
        return string;
    }

    Matcher m = REMOVE_TAGS.matcher(string);
    return m.replaceAll("");
}
Serge
la source
18

Aussi très simple avec Jericho , et vous pouvez conserver une partie de la mise en forme (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());
Josh
la source
4
Jericho a réussi à analyser <br> un saut de ligne. Jsoup et HTMLEditorKit ne pouvaient pas faire cela.
homaxto
Jericho est très capable de faire ce travail, l'a beaucoup utilisé dans des projets appartenant à lui.
Jerry Tian
3
Jéricho a fonctionné comme un charme. Merci pour la suggestion. Une remarque: vous n'avez pas besoin de créer un segment de la chaîne entière. La source étend le segment, donc l'un ou l'autre fonctionne dans le constructeur de rendu.
MrPlow
Jerico semble désormais un peu daté (la dernière version était la 3.4 fin 2015). Cependant, si cela fonctionne toujours bien, alors cela fonctionne toujours bien!
Jonathan Hult
17

La réponse acceptée de faire a simplement Jsoup.parse(html).text()2 problèmes potentiels (avec JSoup 1.7.3):

  • Il supprime les sauts de ligne du texte
  • Il convertit le texte &lt;script&gt;en<script>

Si vous l'utilisez pour vous protéger contre XSS, c'est un peu ennuyeux. Voici ma meilleure image d'une solution améliorée, utilisant à la fois JSoup et Apache StringEscapeUtils:

// breaks multi-level of escaping, preventing &amp;lt;script&amp;gt; to be rendered as <script>
String replace = input.replace("&amp;", "");
// decode any encoded html, preventing &lt;script&gt; to be rendered as <script>
String html = StringEscapeUtils.unescapeHtml(replace);
// remove all html tags, but maintain line breaks
String clean = Jsoup.clean(html, "", Whitelist.none(), new Document.OutputSettings().prettyPrint(false));
// decode html again to convert character entities back into text
return StringEscapeUtils.unescapeHtml(clean);

Notez que la dernière étape est parce que je dois utiliser la sortie en texte brut. Si vous n'avez besoin que d'une sortie HTML, vous devriez pouvoir la supprimer.

Et voici un tas de cas de test (entrée à sortie):

{"regular string", "regular string"},
{"<a href=\"link\">A link</a>", "A link"},
{"<script src=\"http://evil.url.com\"/>", ""},
{"&lt;script&gt;", ""},
{"&amp;lt;script&amp;gt;", "lt;scriptgt;"}, // best effort
{"\" ' > < \n \\ é å à ü and & preserved", "\" ' > < \n \\ é å à ü and & preserved"}

Si vous trouvez un moyen de l'améliorer, faites-le moi savoir.

Damien
la source
2
Cela échouera contre quelque chose comme &#38;lt;script&#38;gt;alert('Evil script executed');&#38;lt;/script&#38;gt;. Il en va de même &#x26;. JSoup ne convertit pas &lt;script&gt; into <script>, il le fait parce que vous appelez StringEscapeUtils.unescapeHtmlaprès que JSoup ait nettoyé l'entrée.
Guillaume Polet
15

Sur Android, essayez ceci:

String result = Html.fromHtml(html).toString();
Ameen Maheen
la source
Ça y est! il a supprimé tout le
code
1
Vous utilisez toujours des extraits de code pour du code normal. Les extraits de code ne sont censés être utilisés que pour du code HTML ou javascript ou tout autre code pouvant être exécuté dans le navigateur. Vous ne pouvez pas exécuter Java dans le navigateur. Utilisez des blocs de code normaux à l'avenir ... Je vais éditer votre réponse pour vous cette fois et corriger le formatage, etc., mais ne le faites plus à l'avenir. Ce n'est pas la première fois que je vous en parle ...
Xaver Kapeller
1
@PaulCroarkin c'est la bibliothèque dans le sdk android. android.text.Html
Ameen Maheen
1
Impressionnant. Suppression de toutes les balises html.
user3144836
2
semble familier, comme ma réponse de 2011.
Ken Goodridge
11

L'échappement HTML est vraiment difficile à faire correctement - je suggérerais certainement d'utiliser le code de bibliothèque pour ce faire, car c'est beaucoup plus subtil que vous ne le pensez. Consultez StringEscapeUtils d' Apache pour une assez bonne bibliothèque pour gérer cela en Java.

Tim Howland
la source
C'est le genre de chose que je recherche, mais je veux supprimer le code HTML au lieu de l'échapper.
Mason
voulez-vous supprimer le html ou le convertir en texte brut? Supprimer le code HTML d'une longue chaîne avec des balises br et des entités HTML peut entraîner un désordre illisible.
Tim Howland,
4
StringEscapeUtils.unescapeHtml ne supprime pas le HTML
Erin Drummond
5
De bonnes informations sur les utilitaires à utiliser pour échapper mais sans répondre à la question.
Alex
3
Réponse confuse. Enlever! = Unescaping
Lluis Martinez
7

Cela devrait fonctionner -

utilisez ceci

  text.replaceAll('<.*?>' , " ") -> This will replace all the html tags with a space.

et ça

  text.replaceAll('&.*?;' , "")-> this will replace all the tags which starts with "&" and ends with ";" like &nbsp;, &amp;, &gt; etc.
Sandeep1699
la source
1
Généralement, les réponses sont beaucoup plus utiles si elles incluent une explication de ce que le code est censé faire.
Peter
6

Vous voudrez peut-être remplacer <br/>et</p> des étiquettes avec des sauts de ligne avant de se dénuder le code HTML pour l' empêcher de devenir un gâchis illisible comme le suggère Tim.

La seule façon dont je peux penser à supprimer des balises HTML, mais de laisser du non-HTML entre les crochets angulaires serait de comparer avec une liste de balises HTML . Quelque chose dans ce sens ...

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

Décodez ensuite des caractères spéciaux tels que HTML &amp;. Le résultat ne doit pas être considéré comme désinfecté.

rusé
la source
5

Alternativement, on peut utiliser HtmlCleaner :

private CharSequence removeHtmlFrom(String html) {
    return new HtmlCleaner().clean(html).getText();
}
Stephan
la source
2
HtmlCleaner fonctionne bien, garde les sauts de ligne et a une version récente (2.21 en mai 2017).
Jonathan Hult
4

La réponse acceptée n'a pas fonctionné pour moi pour le cas de test que j'ai indiqué: le résultat de "a <b ou b> c" est "ab ou b> c".

J'ai donc utilisé TagSoup à la place. Voici une photo qui a fonctionné pour mon cas de test (et quelques autres):

import java.io.IOException;
import java.io.StringReader;
import java.util.logging.Logger;

import org.ccil.cowan.tagsoup.Parser;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * Take HTML and give back the text part while dropping the HTML tags.
 *
 * There is some risk that using TagSoup means we'll permute non-HTML text.
 * However, it seems to work the best so far in test cases.
 *
 * @author dan
 * @see <a href="http://home.ccil.org/~cowan/XML/tagsoup/">TagSoup</a> 
 */
public class Html2Text2 implements ContentHandler {
private StringBuffer sb;

public Html2Text2() {
}

public void parse(String str) throws IOException, SAXException {
    XMLReader reader = new Parser();
    reader.setContentHandler(this);
    sb = new StringBuffer();
    reader.parse(new InputSource(new StringReader(str)));
}

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

@Override
public void characters(char[] ch, int start, int length)
    throws SAXException {
    for (int idx = 0; idx < length; idx++) {
    sb.append(ch[idx+start]);
    }
}

@Override
public void ignorableWhitespace(char[] ch, int start, int length)
    throws SAXException {
    sb.append(ch);
}

// The methods below do not contribute to the text
@Override
public void endDocument() throws SAXException {
}

@Override
public void endElement(String uri, String localName, String qName)
    throws SAXException {
}

@Override
public void endPrefixMapping(String prefix) throws SAXException {
}


@Override
public void processingInstruction(String target, String data)
    throws SAXException {
}

@Override
public void setDocumentLocator(Locator locator) {
}

@Override
public void skippedEntity(String name) throws SAXException {
}

@Override
public void startDocument() throws SAXException {
}

@Override
public void startElement(String uri, String localName, String qName,
    Attributes atts) throws SAXException {
}

@Override
public void startPrefixMapping(String prefix, String uri)
    throws SAXException {
}
}
dfrankow
la source
4

Je sais que c'est vieux, mais je travaillais juste sur un projet qui m'obligeait à filtrer le HTML et cela a bien fonctionné:

noHTMLString.replaceAll("\\&.*?\\;", "");

au lieu de cela:

html = html.replaceAll("&nbsp;","");
html = html.replaceAll("&amp;"."");
rqualis
la source
4

Voici une mise à jour légèrement plus étoffée pour essayer de gérer la mise en forme des pauses et des listes. J'ai utilisé la sortie d'Amaya comme guide.

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Stack;
import java.util.logging.Logger;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;

public class HTML2Text extends HTMLEditorKit.ParserCallback {
    private static final Logger log = Logger
            .getLogger(Logger.GLOBAL_LOGGER_NAME);

    private StringBuffer stringBuffer;

    private Stack<IndexType> indentStack;

    public static class IndexType {
        public String type;
        public int counter; // used for ordered lists

        public IndexType(String type) {
            this.type = type;
            counter = 0;
        }
    }

    public HTML2Text() {
        stringBuffer = new StringBuffer();
        indentStack = new Stack<IndexType>();
    }

    public static String convert(String html) {
        HTML2Text parser = new HTML2Text();
        Reader in = new StringReader(html);
        try {
            // the HTML to convert
            parser.parse(in);
        } catch (Exception e) {
            log.severe(e.getMessage());
        } finally {
            try {
                in.close();
            } catch (IOException ioe) {
                // this should never happen
            }
        }
        return parser.getText();
    }

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

    public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
        log.info("StartTag:" + t.toString());
        if (t.toString().equals("p")) {
            if (stringBuffer.length() > 0
                    && !stringBuffer.substring(stringBuffer.length() - 1)
                            .equals("\n")) {
                newLine();
            }
            newLine();
        } else if (t.toString().equals("ol")) {
            indentStack.push(new IndexType("ol"));
            newLine();
        } else if (t.toString().equals("ul")) {
            indentStack.push(new IndexType("ul"));
            newLine();
        } else if (t.toString().equals("li")) {
            IndexType parent = indentStack.peek();
            if (parent.type.equals("ol")) {
                String numberString = "" + (++parent.counter) + ".";
                stringBuffer.append(numberString);
                for (int i = 0; i < (4 - numberString.length()); i++) {
                    stringBuffer.append(" ");
                }
            } else {
                stringBuffer.append("*   ");
            }
            indentStack.push(new IndexType("li"));
        } else if (t.toString().equals("dl")) {
            newLine();
        } else if (t.toString().equals("dt")) {
            newLine();
        } else if (t.toString().equals("dd")) {
            indentStack.push(new IndexType("dd"));
            newLine();
        }
    }

    private void newLine() {
        stringBuffer.append("\n");
        for (int i = 0; i < indentStack.size(); i++) {
            stringBuffer.append("    ");
        }
    }

    public void handleEndTag(HTML.Tag t, int pos) {
        log.info("EndTag:" + t.toString());
        if (t.toString().equals("p")) {
            newLine();
        } else if (t.toString().equals("ol")) {
            indentStack.pop();
            ;
            newLine();
        } else if (t.toString().equals("ul")) {
            indentStack.pop();
            ;
            newLine();
        } else if (t.toString().equals("li")) {
            indentStack.pop();
            ;
            newLine();
        } else if (t.toString().equals("dd")) {
            indentStack.pop();
            ;
        }
    }

    public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
        log.info("SimpleTag:" + t.toString());
        if (t.toString().equals("br")) {
            newLine();
        }
    }

    public void handleText(char[] text, int pos) {
        log.info("Text:" + new String(text));
        stringBuffer.append(text);
    }

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

    public static void main(String args[]) {
        String html = "<html><body><p>paragraph at start</p>hello<br />What is happening?<p>this is a<br />mutiline paragraph</p><ol>  <li>This</li>  <li>is</li>  <li>an</li>  <li>ordered</li>  <li>list    <p>with</p>    <ul>      <li>another</li>      <li>list        <dl>          <dt>This</dt>          <dt>is</dt>            <dd>sdasd</dd>            <dd>sdasda</dd>            <dd>asda              <p>aasdas</p>            </dd>            <dd>sdada</dd>          <dt>fsdfsdfsd</dt>        </dl>        <dl>          <dt>vbcvcvbcvb</dt>          <dt>cvbcvbc</dt>            <dd>vbcbcvbcvb</dd>          <dt>cvbcv</dt>          <dt></dt>        </dl>        <dl>          <dt></dt>        </dl></li>      <li>cool</li>    </ul>    <p>stuff</p>  </li>  <li>cool</li></ol><p></p></body></html>";
        System.out.println(convert(html));
    }
}
Mike
la source
4

Utilisation Html.fromHtml

Les balises HTML sont

<a href=”…”> <b>,  <big>, <blockquote>, <br>, <cite>, <dfn>
<div align=”…”>,  <em>, <font size=”…” color=”…” face=”…”>
<h1>,  <h2>, <h3>, <h4>,  <h5>, <h6>
<i>, <p>, <small>
<strike>,  <strong>, <sub>, <sup>, <tt>, <u>

Selon les documentations officielles d'Android, toutes les balises dans le HTML s'afficheront comme une chaîne de remplacement générique que votre programme peut ensuite parcourir et remplacer par de vraies chaînes .

Html.formHtmlprend un Html.TagHandleret un Html.ImageGetter comme arguments ainsi que le texte à analyser.

Exemple

String Str_Html=" <p>This is about me text that the user can put into their profile</p> ";

alors

Your_TextView_Obj.setText(Html.fromHtml(Str_Html).toString());

Production

Il s'agit du texte que l'utilisateur peut mettre dans son profil

IntelliJ Amiya
la source
1
Pas d'utilitaires supplémentaires et s'aligne avec les documents Android. +1
davidbates
4

Voici une autre variante de la façon de tout remplacer (balises HTML | Entités HTML | Espace vide dans le contenu HTML)

content.replaceAll("(<.*?>)|(&.*?;)|([ ]{2,})", ""); où le contenu est une chaîne.

silentsudo
la source
1
Je l'ai un peu amélioré: {code} .replaceAll ("(<. *?>) | (&. * ?;)", "") .replaceAll ("\\ s {2,}", "") { code} Parce que souvent ces balises sont juste à côté du texte. Et après avoir supprimé les balises, changez les 2 espaces d'écriture et plus en un seul.
Ondřej Stašek
4

Vous pouvez simplement utiliser le filtre HTML par défaut d'Android

    public String htmlToStringFilter(String textToFilter){

    return Html.fromHtml(textToFilter).toString();

    }

La méthode ci-dessus renverra la chaîne filtrée HTML pour votre entrée.

Anuraganu Punalur
la source
3

Une autre façon peut être d'utiliser la classe com.google.gdata.util.common.html.HtmlToText comme

MyWriter.toConsole(HtmlToText.htmlToPlainText(htmlResponse));

Ce n'est cependant pas un code à l'épreuve des balles et lorsque je l'exécute sur des entrées wikipedia, j'obtiens également des informations de style. Cependant, je crois que pour les petits travaux / simples, ce serait efficace.

rjha94
la source
3

Il semble que vous souhaitiez passer du HTML au texte brut.
Si tel est le cas, consultez www.htmlparser.org. Voici un exemple qui supprime toutes les balises du fichier html trouvé sur une URL.
Il utilise org.htmlparser.beans.StringBean .

static public String getUrlContentsAsText(String url) {
    String content = "";
    StringBean stringBean = new StringBean();
    stringBean.setURL(url);
    content = stringBean.getStrings();
    return content;
}
CSchulz
la source
2

Voici une autre façon de procéder:

public static String removeHTML(String input) {
    int i = 0;
    String[] str = input.split("");

    String s = "";
    boolean inTag = false;

    for (i = input.indexOf("<"); i < input.indexOf(">"); i++) {
        inTag = true;
    }
    if (!inTag) {
        for (i = 0; i < str.length; i++) {
            s = s + str[i];
        }
    }
    return s;
}
étoile Noire
la source
Ou vous pouvez simplement dire, if (input.indexOf ("<")> 0 || input.indexOf (">")> 0) return ""; sinon retourne l'entrée;
Hossein Shahdoost
2

On pourrait également utiliser Apache Tika à cet effet. Par défaut, il préserve les espaces blancs du HTML supprimé, ce qui peut être souhaité dans certaines situations:

InputStream htmlInputStream = ..
HtmlParser htmlParser = new HtmlParser();
HtmlContentHandler htmlContentHandler = new HtmlContentHandler();
htmlParser.parse(htmlInputStream, htmlContentHandler, new Metadata())
System.out.println(htmlContentHandler.getBodyText().trim())
Maksim Sorokin
la source
1
Notez que la méthode d'analyse est déconseillée en faveur de Parse.parse(InputStream, ContentHandler, Metadata, ParseContext).
Jacob van Lingen du
1

Une façon de conserver les informations de nouvelle ligne avec JSoup est de précéder toutes les nouvelles balises de ligne avec une chaîne factice, d'exécuter JSoup et de remplacer la chaîne factice par "\ n".

String html = "<p>Line one</p><p>Line two</p>Line three<br/>etc.";
String NEW_LINE_MARK = "NEWLINESTART1234567890NEWLINEEND";
for (String tag: new String[]{"</p>","<br/>","</h1>","</h2>","</h3>","</h4>","</h5>","</h6>","</li>"}) {
    html = html.replace(tag, NEW_LINE_MARK+tag);
}

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

text = text.replace(NEW_LINE_MARK + " ", "\n\n");
text = text.replace(NEW_LINE_MARK, "\n\n");
RobMen
la source
1
classeString.replaceAll("\\<(/?[^\\>]+)\\>", "\\ ").replaceAll("\\s+", " ").trim() 
Guilherme Oliveira
la source
3
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question pour les lecteurs à l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!
Filnor
0

Mes 5 cents:

String[] temp = yourString.split("&amp;");
String tmp = "";
if (temp.length > 1) {

    for (int i = 0; i < temp.length; i++) {
        tmp += temp[i] + "&";
    }
    yourString = tmp.substring(0, tmp.length() - 1);
}
Alexandre
la source
0

Pour obtenir du texte html brut formaté, vous pouvez le faire:

String BR_ESCAPED = "&lt;br/&gt;";
Element el=Jsoup.parse(html).select("body");
el.select("br").append(BR_ESCAPED);
el.select("p").append(BR_ESCAPED+BR_ESCAPED);
el.select("h1").append(BR_ESCAPED+BR_ESCAPED);
el.select("h2").append(BR_ESCAPED+BR_ESCAPED);
el.select("h3").append(BR_ESCAPED+BR_ESCAPED);
el.select("h4").append(BR_ESCAPED+BR_ESCAPED);
el.select("h5").append(BR_ESCAPED+BR_ESCAPED);
String nodeValue=el.text();
nodeValue=nodeValue.replaceAll(BR_ESCAPED, "<br/>");
nodeValue=nodeValue.replaceAll("(\\s*<br[^>]*>){3,}", "<br/><br/>");

Pour obtenir du texte formaté, modifiez <br/> par \ n et modifiez la dernière ligne par:

nodeValue=nodeValue.replaceAll("(\\s*\n){3,}", "<br/><br/>");
surfealokesea
la source
0

Je sais que cela fait un moment que cette question n'a pas été posée, mais j'ai trouvé une autre solution, c'est ce qui a fonctionné pour moi:

Pattern REMOVE_TAGS = Pattern.compile("<.+?>");
    Source source= new Source(htmlAsString);
 Matcher m = REMOVE_TAGS.matcher(sourceStep.getTextExtractor().toString());
                        String clearedHtml= m.replaceAll("");
Itay Sasson
la source
-1

vous pouvez simplement créer une méthode avec multiple replaceAll () comme

String RemoveTag(String html){
   html = html.replaceAll("\\<.*?>","")
   html = html.replaceAll("&nbsp;","");
   html = html.replaceAll("&amp;"."");
   ----------
   ----------
   return html;
}

Utilisez ce lien pour les remplacements les plus courants dont vous avez besoin: http://tunes.org/wiki/html_20special_20characters_20and_20symbols.html

C'est simple mais efficace. J'utilise d'abord cette méthode pour supprimer les fichiers indésirables, mais pas la toute première ligne, c'est-à-dire replaceAll ("\ <. *?>", ""), Puis j'utilise des mots clés spécifiques pour rechercher des index, puis j'utilise .substring (start, end ) méthode pour éliminer les éléments inutiles. Comme c'est plus robuste et vous pouvez identifier exactement ce dont vous avez besoin dans toute la page html.

Rizwan
la source
4
Deux notes. Tout d'abord, cela n'est pas optimal - pour chaque appel replaceAll, Java tentera de compiler le premier argument en tant qu'expression régulière et d'exécuter la chaîne entière pour appliquer cette expression régulière à la chaîne, en traitant à chaque fois quelques dizaines de Ko pour une page HTML standard. Deuxièmement, il est conseillé de ne pas utiliser replaceAll pour remplacer des chaînes simples (non regex), mais d'utiliser à la place replace () (qui remplace également all, contrairement au nom suggéré).
fwielstra
-1

Supprimez les balises HTML de la chaîne. Quelque part, nous devons analyser une chaîne qui est reçue par certaines réponses comme Httpresponse du serveur.

Nous devons donc l'analyser.

Ici, je vais montrer comment supprimer les balises html de la chaîne.

    // sample text with tags

    string str = "<html><head>sdfkashf sdf</head><body>sdfasdf</body></html>";



    // regex which match tags

    System.Text.RegularExpressions.Regex rx = new System.Text.RegularExpressions.Regex("<[^>]*>");



    // replace all matches with empty strin

    str = rx.Replace(str, "");



    //now str contains string without html tags
Satya Prakash
la source
D'où venez-vous new System.Text.RegularExpressions.Regex();?
beresfordt
1
@beresfordt cette réponse s'applique à .NET, pas à Java comme cela a été demandé dans la question
Erin Drummond