Usuń tagi HTML z łańcucha

422

Czy istnieje dobry sposób na usunięcie HTML z ciągu Java? Proste wyrażenie regularne

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

będzie działać, ale rzeczy takie jak &amp;nie będą poprawnie konwertowane, a nie HTML między dwoma nawiasami kątowymi zostanie usunięty (tj. .*?w wyrażeniu regularnym zniknie).

Mason
źródło
2
użyj tego z następującym przewodnikiem: skompiluj 'org.jsoup: jsoup: 1.9.2'
VahidHoseini
1
stackoverflow.com/a/3149645/5733853
VahidHoseini 26.09.16
Zobacz także: stackoverflow.com/a/21838532/363573
Stephan

Odpowiedzi:

572

Użyj parsera HTML zamiast wyrażenia regularnego. To jest bardzo proste z Jsoup .

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

Jsoup również wspiera usuwanie tagów HTML przeciwko konfigurowalny białej listy, co jest bardzo przydatne, jeśli chcesz zezwolić tylko przykład <b>, <i>i <u>.

Zobacz też:

BalusC
źródło
18
Jsoup jest fajny, ale miałem z tym pewne wady. Używam go, aby pozbyć się XSS, więc w zasadzie spodziewam się zwykłego wprowadzania tekstu, ale jakaś zła osoba może spróbować wysłać mi trochę HTML. Używając Jsoup, mogę usunąć cały HTML, ale niestety zmniejsza on również wiele spacji do jednego i usuwa podziały linków (\ n znaków)
Ridcully
7
@Ridcully: do tego chcesz użyć Jsoup#clean()zamiast tego.
BalusC,
3
użycie clean () nadal spowoduje usunięcie dodatkowych spacji i \ n znaków. np .: Jsoup.clean („a \ n b”, Whitelist.none ()) zwraca „a b”
Keith
20
@Zeroows: kończy się to niepowodzeniem <p>Lorem ipsum 1 < 3 dolor sit amet</p>. Znów HTML nie jest zwykłym językiem . To jest całkowicie poza mną, dlaczego wszyscy próbują rzucić na nie wyrażenie regularne, aby przeanalizować części zainteresowania, zamiast używać prawdziwego parsera.
BalusC,
4
Użyj, Jsoup.clean(unsafeString, "", Whitelist.none(), new OutputSettings().prettyPrint(false));aby zachować przełamania linii
Marc Johnen
275

Jeśli piszesz dla Androida, możesz to zrobić ...

android.text.Html.fromHtml(instruction).toString()
Ken Goodridge
źródło
12
Niesamowita wskazówka. :) Jeśli wyświetlasz tekst w TextView, możesz upuścić .toString (), aby zachować również formatowanie.
Lorne Laliberte
1
@Branky To nie próbowałem ... przyjęta odpowiedź działa jak urok
Maverick
Działa świetnie. Wszystkie tagi HTML zostały usunięte z ciągu.
user3144836,
1
To dobrze, ale znaczniki <img> zostały zastąpione dziwnymi rzeczami. Dostałem małe kwadraty, na których był obraz
Bibaswann Bandyopadhyay
1
@BibaswannBandyopadhyay inna odpowiedź pomaga pozbyć się tych postaci
Vince
84

Jeśli użytkownik wejdzie <b>hey!</b>, czy chcesz wyświetlić <b>hey!</b>lub hey!? Jeśli pierwszy, uciekaj mniej niż, i kodowania html ampersands (i opcjonalnie cytuje) i wszystko w porządku. Modyfikacja kodu w celu wdrożenia drugiej opcji to:

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

ale napotkasz problemy, jeśli użytkownik wpisze coś zniekształconego, na przykład <bhey!</b>.

Możesz także sprawdzić JTidy, który przeanalizuje „brudne” dane HTML i powinien dać ci sposób na usunięcie tagów, zachowując tekst.

Problem z próbą usuwania html polega na tym, że przeglądarki mają bardzo łagodny parser, bardziej łagodny niż jakakolwiek biblioteka, którą można znaleźć, więc nawet jeśli zrobisz wszystko, aby usunąć wszystkie tagi (używając powyższej metody zastępowania, biblioteki DOM lub JTidy) , nadal musisz zakodować wszystkie pozostałe znaki specjalne HTML, aby zachować bezpieczeństwo wyników.

Chris Marasti-Georg
źródło
1
Występują również problemy, jeśli wewnątrz zawartości węzła HTML nie ma znaku <lub> bez znaków. <span> Mój wiek to <dużo tekstu> to twój wiek </span>. Myślę, że tylko w 100% można to zrobić za pomocą interfejsu XML DOM (takiego jak SAX lub podobny), aby użyć node.getText ().
Mitja Gustin
29

Innym sposobem jest użycie javax.swing.text.html.HTMLEditorKit do wyodrębnienia tekstu.

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: Usuń tagi HTML z pliku, aby wyodrębnić tylko TEKST

RealHowTo
źródło
5
Wynikiem „a <b lub b> c” jest „ab lub b> c”, co wydaje się niefortunne.
dfrankow
1
To działało dla mnie najlepiej. Musiałem zachować podział linii. Zrobiłem to, dodając tę ​​prostą metodę do parsera: @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: Wyrażenie matematyczne a <b lub b> c należy zapisać w html w następujący sposób: a & lt; b lub b> c
MiguelMunoz
24

Myślę, że najprostszym sposobem filtrowania tagów HTML jest:

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
źródło
18

Również bardzo proste przy użyciu Jericho , i możesz zachować część formatowania (na przykład podziały wierszy i łącza).

    Source htmlSource = new Source(htmlText);
    Segment htmlSeg = new Segment(htmlSource, 0, htmlSource.length());
    Renderer htmlRend = new Renderer(htmlSeg);
    System.out.println(htmlRend.toString());
Josh
źródło
4
Jericho był w stanie przeanalizować do końca linii. Jsoup i HTMLEditorKit nie mogły tego zrobić.
homaxto
Jericho jest bardzo zdolny do wykonania tej pracy, wykorzystał ją często w posiadanych projektach.
Jerry Tian
3
Jerycho działało jak urok. Dzieki za sugestie. Jedna uwaga: nie musisz tworzyć segmentu całego łańcucha. Źródło rozszerza segment, więc albo działa w konstruktorze renderera.
MrPlow,
Jerico wydaje się być trochę przestarzałe (ostatnie wydanie było 3.4 pod koniec 2015 roku). Jeśli jednak nadal działa dobrze, to nadal działa dobrze!
Jonathan Hult,
17

Akceptowana odpowiedź zrobienia Jsoup.parse(html).text()ma po prostu 2 potencjalne problemy (z JSoup 1.7.3):

  • Usuwa podziały linii z tekstu
  • Konwertuje tekst &lt;script&gt;na<script>

Jeśli użyjesz tego do ochrony przed XSS, będzie to trochę denerwujące. Oto mój najlepszy strzał na ulepszone rozwiązanie, używając zarówno JSoup, jak i 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);

Zauważ, że ostatnim krokiem jest to, że muszę użyć danych wyjściowych jako zwykłego tekstu. Jeśli potrzebujesz tylko danych wyjściowych HTML, powinieneś być w stanie je usunąć.

A oto kilka przypadków testowych (dane wejściowe do danych wyjściowych):

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

Jeśli znajdziesz sposób na ulepszenie, daj mi znać.

Damien
źródło
2
To się nie powiedzie &#38;lt;script&#38;gt;alert('Evil script executed');&#38;lt;/script&#38;gt;. To samo dotyczy &#x26;. JSoup nie konwertuje &lt;script&gt; into <script>, robi to, ponieważ wywołujesz StringEscapeUtils.unescapeHtmlpo wyczyszczeniu danych wejściowych przez JSoup.
Guillaume Polet
15

Na Androidzie spróbuj:

String result = Html.fromHtml(html).toString();
Ameen Maheen
źródło
Zrobiło to! usunął cały tekst HTML z tekstu :)
DritanX
1
Zawsze używasz fragmentów kodu do normalnego kodu. Fragmenty kodu powinny być używane tylko w HTML, javascript lub innym kodzie, który można uruchomić w przeglądarce. Nie można uruchomić Java w przeglądarce. W przyszłości użyj normalnych bloków kodu ... Tym razem zredaguję twoją odpowiedź i naprawię formatowanie itp., Ale nie rób tego więcej w przyszłości. To nie pierwszy raz, kiedy ci o tym mówiłem ...
Xaver Kapeller
1
@PaulCroarkin jest to biblioteka wewnątrz Android SDK. android.text.Html
Ameen Maheen
1
Niesamowite. Usunięto wszystkie tagi HTML.
user3144836,
2
wygląda znajomo, podobnie jak moja odpowiedź z 2011 r.
Ken Goodridge
11

Ucieczka HTML jest naprawdę trudna do zrobienia - zdecydowanie sugerowałbym użycie do tego kodu bibliotecznego, ponieważ jest o wiele bardziej subtelny, niż mogłoby się wydawać. Sprawdź StringEscapeUtils Apache'a, aby znaleźć całkiem dobrą bibliotekę do obsługi tego w Javie.

Tim Howland
źródło
Tego właśnie szukam, ale chcę rozebrać kod HTML zamiast go unikać.
Mason
chcesz usunąć HTML, czy też chcesz go przekonwertować na zwykły tekst? Usunięcie kodu HTML z długiego łańcucha z tagami br i encji HTML może spowodować nieczytelny bałagan.
Tim Howland,
4
StringEscapeUtils.unescapeHtml nie usuwa html
Erin Drummond
5
Dobra informacja o narzędziach używanych do odblokowywania, ale nie odpowiadających na pytanie.
Alex
3
Myląca odpowiedź. Usuwanie! = Unescaping
Lluis Martinez
7

To powinno działać -

Użyj tego

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

i to

  text.replaceAll('&.*?;' , "")-> this will replace all the tags which starts with "&" and ends with ";" like &nbsp;, &amp;, &gt; etc.
Sandeep1699
źródło
1
Zasadniczo odpowiedzi są o wiele bardziej przydatne, jeśli zawierają wyjaśnienie, do czego służy kod.
Peter
6

Być może zechcesz zastąpić <br/>i </p>otagować nowymi liniami przed usunięciem HTML, aby nie stał się nieczytelnym bałaganem, jak sugeruje Tim.

Jedynym sposobem, w jaki mogę wymyślić usunięcie tagów HTML, ale pozostawienie kodu innego niż HTML między nawiasami kątowymi, byłoby sprawdzenie na liście tagów HTML . Coś w tym stylu ...

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

Następnie odkoduj znaki specjalne HTML, takie jak &amp;. Wynik nie powinien być uważany za zdezynfekowany.

lisi
źródło
5

Alternatywnie można użyć HtmlCleaner :

private CharSequence removeHtmlFrom(String html) {
    return new HtmlCleaner().clean(html).getText();
}
Stephan
źródło
2
HtmlCleaner działa dobrze, utrzymuje podział linii i ma najnowszą wersję (2.21 w maju 2017 r.).
Jonathan Hult,
4

Przyjęta odpowiedź nie zadziałała dla wskazanego przeze mnie przypadku testowego: wynikiem „a <b lub b> c” jest „ab lub b> c”.

Więc zamiast tego użyłem TagSoup. Oto ujęcie, które zadziałało w moim przypadku testowym (i kilku innych):

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
źródło
4

Wiem, że to stare, ale właśnie pracowałem nad projektem, który wymagał ode mnie filtrowania HTML i działało to dobrze:

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

zamiast tego:

html = html.replaceAll("&nbsp;","");
html = html.replaceAll("&amp;"."");
rqualis
źródło
4

Oto nieco bardziej rozbudowana aktualizacja, aby spróbować poradzić sobie z formatowaniem przerw i list. Użyłem wyników Amayi jako przewodnika.

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));
    }
}
Mikrofon
źródło
4

Posługiwać się Html.fromHtml

Tagi HTML

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

Zgodnie z oficjalnymi dokumentacjami Androida wszelkie tagi w HTML będą wyświetlane jako ogólny ciąg zastępczy, który następnie program może przejść i zastąpić prawdziwymi ciągami .

Html.formHtmlMetoda przyjmuje Html.TagHandlerjako argumenty argument Html.ImageGetter oraz tekst do analizy.

Przykład

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

Następnie

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

Wynik

To o mnie tekst, który użytkownik może umieścić w swoim profilu

IntelliJ Amiya
źródło
1
Bez dodatkowych narzędzi i dostosowuje się do Dokumentów Androida. +1
davidbates
4

Oto jeszcze jeden wariant sposobu zamiany wszystkich (Tagi HTML | Elementy HTML | Puste miejsce w treści HTML)

content.replaceAll("(<.*?>)|(&.*?;)|([ ]{2,})", ""); gdzie treść jest ciągiem.

silentsudo
źródło
1
Trochę go poprawiłem: {code} .replaceAll ("(<. *?>) | (&. * ?;)", "") .replaceAll ("\\ s {2,}", "") { kod} Ponieważ często te tagi są tuż obok tekstu. A po usunięciu tagów zmień wszystkie 2 i więcej pól pisarskich na tylko 1.
Ondřej Stašek
4

Możesz po prostu użyć domyślnego filtra HTML Androida

    public String htmlToStringFilter(String textToFilter){

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

    }

Powyższa metoda zwróci filtrowany ciąg HTML do wprowadzenia.

Anuraganu Punalur
źródło
3

Jeszcze jednym sposobem może być użycie klasy com.google.gdata.util.common.html.HtmlToText, np.

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

Nie jest to jednak kod kuloodporny, a kiedy uruchamiam go na pozycjach wikipedii, również otrzymuję informacje o stylu. Uważam jednak, że w przypadku małych / prostych prac byłoby to skuteczne.

rjha94
źródło
3

Wygląda na to, że chcesz przejść z HTML do zwykłego tekstu.
Jeśli tak jest, spójrz na www.htmlparser.org. Oto przykład, który usuwa wszystkie tagi z pliku HTML znalezionego pod adresem URL.
Wykorzystuje 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
źródło
2

Oto inny sposób, aby to zrobić:

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;
}
czarna Gwiazda
źródło
Lub możesz po prostu powiedzieć, jeśli (input.indexOf ("<")> 0 || input.indexOf (">")> 0) return ""; w przeciwnym razie zwraca dane wejściowe;
Hossein Shahdoost
2

W tym celu można również użyć Apache Tika . Domyślnie zachowuje białe znaki z pozbawionego kodu HTML, co może być pożądane w niektórych sytuacjach:

InputStream htmlInputStream = ..
HtmlParser htmlParser = new HtmlParser();
HtmlContentHandler htmlContentHandler = new HtmlContentHandler();
htmlParser.parse(htmlInputStream, htmlContentHandler, new Metadata())
System.out.println(htmlContentHandler.getBodyText().trim())
Maksim Sorokin
źródło
1
Zauważ, że metoda analizy jest przestarzała na korzyść Parse.parse(InputStream, ContentHandler, Metadata, ParseContext).
Jacob van Lingen
1

Jednym ze sposobów zachowania informacji o nowej linii w JSoup jest poprzedzenie wszystkich nowych tagów linii jakimś fikcyjnym łańcuchem, wykonanie JSoup i zastąpienie fikcyjnego łańcucha "\ 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
źródło
1
classeString.replaceAll("\\<(/?[^\\>]+)\\>", "\\ ").replaceAll("\\s+", " ").trim() 
Guilherme Oliveira
źródło
3
Ten fragment kodu może rozwiązać pytanie, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu. Staraj się również nie tłoczyć kodu objaśniającymi komentarzami, co zmniejsza czytelność zarówno kodu, jak i objaśnień!
Filnor
0

Moje 5 centów:

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);
}
Alexander
źródło
0

Aby uzyskać sformatowany zwykły tekst HTML, możesz to zrobić:

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

Aby uzyskać sformatowany zwykły tekst, zmień <br/> o \ n i zmień ostatni wiersz o:

nodeValue=nodeValue.replaceAll("(\\s*\n){3,}", "<br/><br/>");
surfealokesea
źródło
0

Wiem, że minęło trochę czasu, odkąd zadano to pytanie, ale znalazłem inne rozwiązanie, oto, co zadziałało dla mnie:

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

możesz po prostu stworzyć metodę z wieloma podobnymi replaceAll ()

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

Użyj tego linku, aby znaleźć najczęściej potrzebne zamienniki: http://tunes.org/wiki/html_20special_20characters_20 i_20symbols.html

To proste, ale skuteczne. Najpierw używam tej metody do usuwania śmieci, ale nie do pierwszego wiersza, tj. ReplaceAll („\ <. *?>”, „”), A następnie używam określonych słów kluczowych do wyszukiwania indeksów, a następnie używam .substring (start, end ) metoda usuwania niepotrzebnych rzeczy. Ponieważ jest to bardziej niezawodne i możesz dokładnie wskazać, czego potrzebujesz na całej stronie HTML.

Rizwan
źródło
4
Dwie notatki. Po pierwsze, jest to nieoptymalne - dla każdego wywołania replaceAll Java podejmie próbę skompilowania pierwszego argumentu jako wyrażenia regularnego i przejdzie przez cały ciąg znaków, aby zastosować to wyrażenie regularne, przetwarzając za każdym razem kilkadziesiąt KB dla zwykłej strony HTML. Po drugie, nie zaleca się używania replaceAll do zamiany prostych (nieregexowych) łańcuchów, ale zamiast tego użyj replace () (który również zastępuje wszystkie, w przeciwieństwie do nazwy).
fwielstra
-1

Usuń tagi HTML z łańcucha. Gdzieś musimy przeanalizować jakiś ciąg, który jest odbierany przez niektóre odpowiedzi, takie jak Httpresponse z serwera.

Więc musimy to przeanalizować.

Tutaj pokażę, jak usunąć tagi HTML z ciągu.

    // 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
źródło
Gdzie można dostać new System.Text.RegularExpressions.Regex();od?
beresfordt
1
@beresfordt ta odpowiedź dotyczy .NET, a nie Java, tak jak w pytaniu
Erin Drummond