Frage

Gibt es einen guten Weg, um HTML aus einem Java-String zu entfernen? Eine einfache Regex wie

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

wird funktionieren, aber Dinge wie &amp; wird nicht korrekt und nicht-HTML zwischen den beiden spitzen Klammern umgewandelt werden, werden entfernt (das heißt die .*? in der Regex verschwindet).

War es hilfreich?

Lösung

Verwenden Sie einen HTML-Parser statt regex. Dies ist tot einfach mit Jsoup .

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

Jsoup auch unterstützt HTML-Tags gegen eine anpassbare weißen Liste zu entfernen, was sehr nützlich, wenn Sie zB nur zulassen möchten <b>, <i> und <u>.

Siehe auch:

Andere Tipps

Wenn Sie schreiben für Android Sie können dies tun ...

android.text.Html.fromHtml(instruction).toString()

Wenn der Benutzer <b>hey!</b> eintritt, tun Sie <b>hey!</b> oder hey! angezeigt werden soll? Wenn die ersten, Flucht weniger thans und html-encode Et-Zeichen (und optional Anführungszeichen) ein und du bist in Ordnung. Eine Änderung an Ihrem Code die zweite Option zu implementieren wäre:

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

, aber Sie werden auf Probleme stoßen, wenn der Benutzer etwas fehlerhaft eingibt, wie <bhey!</b>.

Sie können auch Besuche jtidy die „dirty“ html Eingabe analysieren, und sollten Sie einen Weg geben, die Tags zu entfernen, um den Text zu halten.

Das Problem mit dem Versuch, HTML zu entfernen ist, dass Browser hat sehr milde Parser, mildere als jede Bibliothek, die Sie finden können, werden, so dass selbst wenn Sie tun Sie am besten alle Tags strippen (die oben beschriebene Methode ersetzen verwenden, eine DOM-Bibliothek, oder jtidy), werden Sie noch müssen sicherstellen, dass alle verbleibenden HTML-Sonderzeichen codieren Ihre Ausgabe sicher zu halten.

Eine andere Möglichkeit ist die Verwendung javax.swing.text.html.HTMLEditorKit , um den Text zu extrahieren.

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: entfernen HTML-Tags aus einer Datei nur den Text zu extrahieren

Ich denke, dass der einfachste Weg, um die HTML-Tags zu filtern ist:

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

Auch sehr einfach Jericho verwenden, und Sie können einen Teil der Formatierung (Linie behalten Pausen und Links, zum Beispiel).

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

Auf Android, versuchen Sie dies:

String result = Html.fromHtml(html).toString();

HTML Flüchten ist wirklich schwer zu tun rechts- ich auf jeden Fall Bibliothek Code verwenden würde vorschlagen, dies zu tun, da es viel subtiler ist als man denkt. Schauen Sie sich Apache StringEscapeUtils für eine ziemlich gute Bibliothek für den Umgang mit diesem in Java.

Die akzeptierte Antwort einfach zu tun Jsoup.parse(html).text() hat zwei mögliche Probleme (mit JSoup 1.7.3):

  • Es entfernt Zeilenumbrüche aus dem Text
  • Er wandelt Text &lt;script&gt; in <script>

Wenn Sie diese verwenden, um gegen XSS zu schützen, ist dies ein bisschen ärgerlich. Hier ist meine beste Chance auf eine bessere Lösung, wobei sowohl JSoup und 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);

Beachten Sie, dass der letzte Schritt ist, weil ich die Ausgabe als Klartext verwenden müssen. Wenn Sie nur die HTML-Ausgabe benötigen, dann sollten Sie in der Lage sein, es zu entfernen.

Und hier ist ein Bündel von Testfällen (Eingang zum Ausgang):

{"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"}

Wenn Sie einen Weg finden, es besser zu machen, lassen Sie es mich wissen.

Sie mögen vielleicht <br/> und </p> Tags mit Zeilenumbrüchen ersetzen, bevor die HTML-Strippen zu verhindern, dass eine unleserliche Chaos wie Tim schlägt zu werden.

Der einzige Weg, ich Entfernen von HTML-Tags denken kann, aber verlassen Nicht-HTML zwischen spitzen Klammern würde überprüfen gegen ein Liste von HTML-Tags . Etwas in dieser Richtung ...

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

Dann HTML-decode Sonderzeichen wie &amp;. Das Ergebnis sollte nicht desinfiziert werden wird in Betracht gezogen.

Das sollte funktionieren -

verwenden diese

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

und das

  text.replaceAll('&.*?;' , "")-> this will replace all the tags which starts with "&" and ends with ";" like &nbsp;, &amp;, &gt; etc.

Die akzeptierte Antwort hat nicht funktioniert für mich für den Testfall I angegeben: das Ergebnis von "a c" ist "a b oder b> c"

.

Also, ich verwendet tagsoup statt. Hier ist ein Schuss, der für meine Testfall (und ein paar andere) gearbeitet:

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

Ich weiß, das ist alt, aber ich war gerade an einem Projekt arbeiten, das mich erforderlich HTML zu filtern und das hat gut funktioniert:

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

statt dies:

html = html.replaceAll("&nbsp;","");
html = html.replaceAll("&amp;"."");

Hier ist ein leicht mehr konkretisiert Update zu versuchen, einige Formatierungen für Pausen und Listen zu handhaben. Ich benutzte Amayas Ausgabe als Leitfaden.

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

Alternativ kann man benutzen HtmlCleaner :

private CharSequence removeHtmlFrom(String html) {
    return new HtmlCleaner().clean(html).getText();
}

Mit Html.fromHtml

HTML Stichworte sind

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

Wie pro Android offiziellen Dokumentationen alle Tags in der HTML wird als generischer Ersatz String , die Ihr Programm dann durch und ersetzen mit echten Strings .

Html.formHtml Methode verwendet ein Html.TagHandler und ein Html.ImageGetter als Argumente sowie der Text zu analysieren.

Beispiel

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

Dann

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

Output

Hier geht es um mich Text, dass der Benutzer in sein Profil setzen kann

Eine weitere Möglichkeit kann sein com.google.gdata.util.common.html.HtmlToText Klasse zu verwenden wie

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

Das ist kein Beweis Kugel Code obwohl und wenn ich laufe es auf Wikipedia Einträge Ich erhalte style info auch. Jedoch habe ich für kleine / einfache Arbeitsplätze glauben, dies wäre wirksam.

Es klingt wie Sie von HTML in Klartext gehen.
Wenn das der Fall Blick auf www.htmlparser.org. Hier ist ein Beispiel, das bei einer URL gefunden alle Tags aus der HTML-Datei Streifen.
Es macht Gebrauch von org.htmlparser.beans.StringBean .

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

Hier ist eine andere Art und Weise, es zu tun:

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

Hier ist eine weitere Variante, wie alle (HTML-Tags | HTML Entities | leerer Raum in HTML-Inhalt) ersetzen

content.replaceAll("(<.*?>)|(&.*?;)|([ ]{2,})", ""); wo Inhalt ist ein String.

könnte man auch verwenden Apache Tika für diesen Zweck . Standardmäßig bewahrt es Leerzeichen aus dem abgestreiften html, die in bestimmten Situationen erwünscht sein kann:

InputStream htmlInputStream = ..
HtmlParser htmlParser = new HtmlParser();
HtmlContentHandler htmlContentHandler = new HtmlContentHandler();
htmlParser.parse(htmlInputStream, htmlContentHandler, new Metadata())
System.out.println(htmlContentHandler.getBodyText().trim())

Eine Möglichkeit, new-line-Info mit JSoup zu behalten ist es, alle neuen Zeile Tags mit einigen Dummy-Folge vorangehen, führen JSoup und Dummy-Zeichenfolge ersetzen mit "\ 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");

Sie können einfach die Standard-HTML-Filter Android verwenden

    public String htmlToStringFilter(String textToFilter){

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

    }

Das obige Verfahren wird die HTML-gefilterte Zeichenkette für Ihre Eingabe zurück.

Meine 5 Cent:

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

Um formateed einfacher HTML-Text können Sie das tun:

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/>");

Um auf formateed Klartext ändern
durch \ n und letzte Zeile ändern:

nodeValue=nodeValue.replaceAll("(\\s*\n){3,}", "<br/><br/>");
classeString.replaceAll("\\<(/?[^\\>]+)\\>", "\\ ").replaceAll("\\s+", " ").trim() 

Sie können einfach eine Methode mit mehreren replaceAll () wie

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

Verwenden Sie diesen Link für die gängigsten Ersatz benötigen Sie: http://tunes.org/wiki/html_20special_20characters_20and_20symbols.html

Es ist einfach, aber effektiv. Ich benutze diese Methode zuerst die Junk, aber nicht die erste Zeile dh replaceAll ( „\ <. *?>“, „“), Zu entfernen und später i bestimmte Schlüsselwörter verwenden, um Indizes zu suchen und verwenden Sie dann .substring (Start, Ende ) Verfahren unnötige Material abzustreifen. Da diese robuster ist und Sie können Punkt Pin genau das, was Sie in der gesamten HTML-Seite müssen.

entfernen HTML-Tags aus String. Irgendwo müssen wir einige Zeichenfolge analysieren, die von einigen Antworten wie Httpresponse vom Server empfangen wird.

So müssen wir es analysieren.

Hier werde ich zeigen, wie HTML-Tags aus Zeichenfolge zu entfernen.

    // 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top