Xóa các thẻ HTML khỏi Chuỗi


422

Có cách nào tốt để xóa HTML khỏi chuỗi Java không? Một regex đơn giản như

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

sẽ hoạt động, nhưng những thứ như &amp;sẽ không được chuyển đổi chính xác và không phải HTML giữa hai dấu ngoặc góc sẽ bị xóa (tức là .*?trong biểu thức chính quy sẽ biến mất).


2
sử dụng hướng dẫn này với hướng dẫn sau: biên dịch 'org.jsoup: jsoup: 1.9.2'
VahidHoseini


Câu trả lời:


572

Sử dụng trình phân tích cú pháp HTML thay vì regex. Điều này thật đơn giản với Jsoup .

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

Jsoup cũng hỗ trợ xóa các thẻ HTML đối với danh sách trắng có thể tùy chỉnh, rất hữu ích nếu bạn chỉ muốn cho phép <b>, ví dụ , <i><u>.

Xem thêm:


18
Jsoup là tốt, nhưng tôi đã gặp một số nhược điểm với nó. Tôi sử dụng nó để loại bỏ XSS, vì vậy về cơ bản tôi mong đợi một kiểu nhập văn bản đơn giản, nhưng một số kẻ xấu có thể cố gắng gửi cho tôi một số HTML. Sử dụng Jsoup, tôi có thể xóa tất cả HTML, nhưng thật không may, nó cũng thu nhỏ nhiều khoảng trống thành một và xóa các ngắt liên kết (\ n ký tự)
Ridcully

7
@Ridcully: thay vào đó bạn muốn sử dụng Jsoup#clean().
BalusC

3
sử dụng Clean () vẫn sẽ khiến các khoảng trắng thừa và \ n ký tự bị xóa. ví dụ: Jsoup.clean ("a \ n b", Whitelist.none ()) trả về "a b"
Keith

20
@Zeroows: thất bại thảm hại trên <p>Lorem ipsum 1 < 3 dolor sit amet</p>. Một lần nữa, HTML không phải là ngôn ngữ thông thường . Nó hoàn toàn vượt xa tôi tại sao mọi người cứ cố gắng ném regex vào nó để phân tích các phần quan tâm thay vì sử dụng một trình phân tích cú pháp thực sự.
BalusC

4
sử dụng Jsoup.clean(unsafeString, "", Whitelist.none(), new OutputSettings().prettyPrint(false));để bảo vệ các ngắt dòng
Marc Johnen

275

Nếu bạn đang viết cho Android, bạn có thể làm điều này ...

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

12
Mẹo tuyệt vời. :) Nếu bạn đang hiển thị văn bản trong TextView, bạn cũng có thể bỏ .toString () để giữ một số định dạng.
Lorne Laliberte

1
@Branky Không phải tôi đã thử ... câu trả lời được chấp nhận hoạt động như bùa mê
Maverick

Công trình tuyệt vời. Tất cả các thẻ html đã bị xóa khỏi Chuỗi.
dùng3144836

1
Điều này là tốt, nhưng các thẻ <img> được thay thế bằng một số điều kỳ quái. Tôi có những ô vuông nhỏ có hình ảnh
Bibaswann Bandyopadhyay

1
@BibaswannBandyopadhyay một câu trả lời khác giúp loại bỏ những nhân vật này
Vince

84

Nếu người dùng vào <b>hey!</b>, bạn có muốn hiển thị <b>hey!</b>hay hey!không? Nếu là người đầu tiên, hãy thoát các lệnh ít mã hóa và mã hóa html (và trích dẫn tùy chọn) và bạn vẫn ổn. Một sửa đổi cho mã của bạn để thực hiện tùy chọn thứ hai sẽ là:

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

nhưng bạn sẽ gặp vấn đề nếu người dùng nhập vào một cái gì đó không đúng định dạng, như thế nào <bhey!</b>.

Bạn cũng có thể kiểm tra JTidy sẽ phân tích cú pháp html "bẩn" và sẽ cung cấp cho bạn cách xóa thẻ, giữ văn bản.

Vấn đề với việc cố gắng tách html là các trình duyệt có trình phân tích cú pháp rất khoan dung, khoan dung hơn bất kỳ thư viện nào bạn có thể tìm thấy, vì vậy ngay cả khi bạn cố hết sức để loại bỏ tất cả các thẻ (sử dụng phương pháp thay thế ở trên, thư viện DOM hoặc JTidy) , bạn sẽ vẫn cần đảm bảo mã hóa mọi ký tự đặc biệt HTML còn lại để giữ đầu ra của bạn an toàn.


1
Bạn cũng gặp vấn đề, nếu có dấu <hoặc> không thoát ra bên trong nội dung nút html. <span> Tuổi của tôi là <rất nhiều văn bản> sau đó là tuổi của bạn </ span>. Tôi nghĩ rằng chỉ có 100% cách để thực hiện việc này là thông qua một số giao diện XML DOM (như SAX hoặc tương tự), để sử dụng node.getText ().
Mitja Gustin

29

Một cách khác là sử dụng javax.swing.text.html.HTMLEditorKit để trích xuất văn bản.

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: Xóa các thẻ HTML khỏi một tệp để chỉ trích xuất văn bản


5
Kết quả của "a <b hoặc b> c" là "ab hoặc b> c", điều này có vẻ không may.
dfrankow

1
Điều này làm việc tốt nhất cho tôi. Tôi cần phải bảo toàn ngắt dòng. Tôi đã thực hiện bằng cách thêm phương thức đơn giản này vào trình phân tích cú pháp: @Override public void handleStartTag (HTML.Tag t, MutableAttribution Set a, int pos) {if (t == HTML.Tag.P | {s.append ('\ n'); }}
MiguelMunoz

1
dfrankow: Biểu thức toán học a <b hoặc b> c nên được viết bằng html như thế này: a & lt; b hoặc b & gt; c
MiguelMunoz

24

Tôi nghĩ rằng cách đơn giản nhất để lọc các thẻ html là:

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

18

Cũng rất đơn giản khi sử dụng Jericho và bạn có thể giữ lại một số định dạng (ví dụ ngắt dòng và liên kết).

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

4
Giê-ri-cô đã có thể phân tích <br> để ngắt dòng. Jsoup và HTMLEditorKit không thể làm điều đó.
homaxto

Jericho rất có khả năng làm công việc này, đã sử dụng nó rất nhiều trong các dự án thuộc sở hữu.
Jerry Tian

3
Giê-ri-cô làm việc như một lá bùa. Cám ơn vì sự gợi ý. Một lưu ý: bạn không phải tạo Phân đoạn cho toàn bộ chuỗi. Nguồn mở rộng Phân đoạn, do đó, hoặc hoạt động trong hàm tạo Trình kết xuất.
MrPlow

Jerico bây giờ có vẻ là một chút ngày (bản phát hành cuối cùng là 3,4 vào cuối năm 2015). Tuy nhiên, nếu nó vẫn hoạt động tốt, thì nó vẫn hoạt động tốt!
Jonathan Hult

17

Câu trả lời được chấp nhận khi thực hiện đơn giản Jsoup.parse(html).text()có 2 vấn đề tiềm ẩn (với JSoup 1.7.3):

  • Nó loại bỏ ngắt dòng khỏi văn bản
  • Nó chuyển đổi văn bản &lt;script&gt;thành<script>

Nếu bạn sử dụng điều này để bảo vệ chống lại XSS, điều này hơi khó chịu. Đây là cách tốt nhất của tôi về một giải pháp cải tiến, sử dụng cả JSoup và 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);

Lưu ý rằng bước cuối cùng là vì tôi cần sử dụng đầu ra dưới dạng văn bản thuần túy. Nếu bạn chỉ cần đầu ra HTML thì bạn sẽ có thể loại bỏ nó.

Và đây là một loạt các trường hợp thử nghiệm (đầu vào đầu ra):

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

Nếu bạn tìm thấy một cách để làm cho nó tốt hơn, xin vui lòng cho tôi biết.


2
Điều này sẽ thất bại chống lại một cái gì đó như &#38;lt;script&#38;gt;alert('Evil script executed');&#38;lt;/script&#38;gt;. Cùng đi cho &#x26;. JSoup không chuyển đổi &lt;script&gt; into <script>, nó thực hiện điều đó bởi vì bạn gọi StringEscapeUtils.unescapeHtmlsau khi JSoup dọn sạch đầu vào.
Polilla Guillaume

15

Trên Android, hãy thử điều này:

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

Điều này đã làm nó! nó đã xóa tất cả html nội tuyến khỏi văn bản :)
DritanX 15/05/2015

1
Bạn luôn sử dụng đoạn mã cho mã thông thường. Đoạn mã chỉ được sử dụng cho HTML hoặc javascript hoặc mã khác có thể chạy trong trình duyệt. Bạn không thể chạy Java trong trình duyệt. Sử dụng các khối mã thông thường trong tương lai ... Tôi sẽ chỉnh sửa câu trả lời của bạn cho bạn lần này và sửa định dạng, v.v., nhưng vui lòng không làm điều này nữa trong tương lai. Đây không phải là lần đầu tiên tôi nói với bạn về điều này ...
Xaver Kapeller

1
@PaulCroarkin đây là thư viện bên trong sdk android. android.text.Html
Ameen Maheen

1
Tuyệt vời. Đã xóa tất cả các thẻ html.
dùng3144836

2
trông quen thuộc, giống như câu trả lời của tôi từ năm 2011
Ken Goodridge

11

HTML Escaping thực sự rất khó để thực hiện đúng - Tôi chắc chắn khuyên bạn nên sử dụng mã thư viện để làm điều này, vì nó tinh tế hơn nhiều so với bạn nghĩ. Hãy xem StringEscapeUtils của Apache để có một thư viện khá tốt để xử lý việc này trong Java.


Đây là thứ tôi đang tìm kiếm nhưng tôi muốn loại bỏ HTML thay vì thoát khỏi nó.
Mason

Bạn có muốn tách html hay bạn muốn chuyển đổi nó thành văn bản thuần túy? Tước HTML từ một chuỗi dài với các thẻ br và các thực thể HTML có thể dẫn đến một mớ hỗn độn không thể đọc được.
Tim Howland

4
StringEscapeUtils.unescapeHtml không tước html
Erin Drumond

5
Thông tin tốt về các dụng cụ để sử dụng cho unescaping nhưng không trả lời câu hỏi.
Alex

3
Câu trả lời khó hiểu. Xóa! = Không chú ý
Lluis Martinez

7

Điều này sẽ làm việc -

dùng cái này

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

và điều này

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

1
Nói chung, câu trả lời sẽ hữu ích hơn nhiều nếu chúng bao gồm một lời giải thích về những gì mã được dự định làm.
Peter

6

Bạn có thể muốn thay thế <br/></p>gắn thẻ bằng các dòng mới trước khi tước HTML để ngăn nó trở thành một mớ hỗn độn không thể đọc được như Tim gợi ý.

Cách duy nhất tôi có thể nghĩ đến để xóa các thẻ HTML nhưng để lại không phải HTML giữa các dấu ngoặc góc sẽ là kiểm tra danh sách các thẻ HTML . Một cái gì đó dọc theo những dòng này ...

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

Sau đó, HTML giải mã các ký tự đặc biệt như &amp;. Kết quả không nên được coi là vệ sinh.


5

Ngoài ra, người ta có thể sử dụng HtmlCleaner :

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

2
HtmlCleaner hoạt động tốt, giữ ngắt dòng và có bản phát hành gần đây (2.21 vào tháng 5 năm 2017).
Jonathan Hult

4

Câu trả lời được chấp nhận không phù hợp với tôi đối với trường hợp thử nghiệm mà tôi đã chỉ ra: kết quả của "a <b hoặc b> c" là "ab hoặc b> c".

Vì vậy, tôi đã sử dụng TagSoup thay thế. Đây là một shot hoạt động cho trường hợp thử nghiệm của tôi (và một vài người khác):

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

4

Tôi biết điều này đã cũ, nhưng tôi chỉ đang thực hiện một dự án yêu cầu tôi lọc HTML và điều này hoạt động tốt:

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

thay vì điều này:

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

4

Đây là một bản cập nhật nhẹ nhàng hơn để cố gắng xử lý một số định dạng cho các ngắt và danh sách. Tôi đã sử dụng đầu ra của Amaya như một hướng dẫn.

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

4

Sử dụng Html.fromHtml

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

Theo Tài liệu chính thức của Android, bất kỳ thẻ nào trong HTML sẽ hiển thị dưới dạng Chuỗi thay thế chung mà chương trình của bạn có thể đi qua và thay thế bằng các chuỗi thực .

Html.formHtmlphương thức lấy một Html.TagHandlervà một Html.ImageGetter làm đối số cũng như văn bản để phân tích cú pháp.

Thí dụ

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

Sau đó

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

Đầu ra

Đây là về tôi văn bản mà người dùng có thể đưa vào hồ sơ của họ


1
Không có tiện ích bổ sung và phù hợp với Tài liệu Android. +1
davidbates 30/03/2016

4

Đây là một biến thể nữa về cách thay thế tất cả (Thẻ HTML | Thực thể HTML | Không gian trống trong nội dung HTML)

content.replaceAll("(<.*?>)|(&.*?;)|([ ]{2,})", ""); trong đó nội dung là một chuỗi.


1
Tôi đã cải thiện nó một chút: {code} .replaceAll ("(<. *?>) | (&. *?;)", "") .ReplaceAll ("\\ s {2,}", "") { code} Bởi vì những thẻ đó thường nằm bên cạnh văn bản. Và sau khi xóa các thẻ, thay đổi tất cả 2 và nhiều hơn các vùng ghi thành 1.
Ondřej Stašek

4

Bạn chỉ có thể sử dụng bộ lọc HTML mặc định của Android

    public String htmlToStringFilter(String textToFilter){

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

    }

Phương pháp trên sẽ trả về chuỗi đã lọc HTML cho đầu vào của bạn.


3

Một cách nữa có thể là sử dụng lớp com.google.gdata.util.common.html.HtmlToText như

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

Đây không phải là mã bằng chứng đạn và khi tôi chạy nó trên các mục wikipedia tôi cũng nhận được thông tin về kiểu dáng. Tuy nhiên tôi tin rằng đối với các công việc nhỏ / đơn giản, điều này sẽ có hiệu quả.


3

Có vẻ như bạn muốn chuyển từ HTML sang văn bản thuần túy.
Nếu đó là trường hợp, hãy xem www.htmlparser.org. Dưới đây là một ví dụ loại bỏ tất cả các thẻ ra khỏi tệp html được tìm thấy tại một URL.
Nó sử dụng org.htmlparser.beans.StringBean .

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

2

Đây là một cách khác để làm điều đó:

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

Hoặc bạn chỉ có thể nói, if (input.indexOf ("<")> 0 || input.indexOf (">")> 0) return ""; khác trả lại đầu vào;
Hossein Shahdoost

2

Người ta cũng có thể sử dụng Apache Tika cho mục đích này. Theo mặc định, nó bảo toàn khoảng trắng từ html bị tước, có thể được yêu cầu trong một số trường hợp:

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

1
Lưu ý rằng phương pháp phân tích cú pháp không được ủng hộ Parse.parse(InputStream, ContentHandler, Metadata, ParseContext).
Jacob van Lingen

1

Một cách để giữ lại thông tin dòng mới với JSoup là đặt trước tất cả các thẻ dòng mới bằng một số chuỗi giả, thực thi JSoup và thay thế chuỗi giả bằng "\ 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");

1
classeString.replaceAll("\\<(/?[^\\>]+)\\>", "\\ ").replaceAll("\\s+", " ").trim() 

3
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Xin vui lòng cố gắng không làm đông mã của bạn với các bình luận giải thích, điều này làm giảm khả năng đọc của cả mã và các giải thích!
Filnor

0

5 xu của tôi:

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

0

Để có được văn bản html đơn giản định dạng, bạn có thể làm điều đó:

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

Để có được thay đổi văn bản đơn giản định dạng <br/> bởi \ n và thay đổi dòng cuối cùng bằng cách:

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

0

Tôi biết đã được một lúc kể từ khi câu hỏi này được hỏi, nhưng tôi đã tìm thấy một giải pháp khác, đây là những gì làm việc cho tôi:

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

-1

bạn có thể chỉ cần tạo một phương thức với nhiều thay thế ()

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

Sử dụng liên kết này cho hầu hết các thay thế phổ biến bạn cần: http://tunes.org/wiki/html_20special_20char character_20and_20symbols.html

Nó đơn giản nhưng hiệu quả. Trước tiên, tôi sử dụng phương pháp này để loại bỏ rác nhưng không phải là dòng đầu tiên, ví dụ: ) phương pháp để loại bỏ những thứ không cần thiết. Vì điều này mạnh mẽ hơn và bạn có thể xác định chính xác những gì bạn cần trong toàn bộ trang html.


4
Hai lưu ý. Đầu tiên, đây là tối ưu - đối với mỗi cuộc gọi thay thế, Java sẽ cố gắng biên dịch đối số đầu tiên dưới dạng regex và chạy qua toàn bộ chuỗi để áp dụng biểu thức chính quy đó vào chuỗi, mỗi lần xử lý vài chục KB cho một trang HTML thông thường. Thứ hai, không nên sử dụng thay thế AllAll để thay thế các chuỗi đơn giản (không phải regex), mà thay vào đó sử dụng thay thế () (cũng thay thế tất cả, không giống như tên cho thấy).
fwielstra

-1

Xóa các thẻ HTML khỏi chuỗi. Ở đâu đó chúng ta cần phân tích một số chuỗi được nhận bởi một số phản hồi như Httpresponse từ máy chủ.

Vì vậy, chúng ta cần phân tích nó.

Ở đây tôi sẽ chỉ cho bạn cách xóa thẻ html khỏi chuỗi.

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

Bạn lấy new System.Text.RegularExpressions.Regex();từ đâu
beresfordt

1
@beresfordt câu trả lời này áp dụng cho .NET, không phải Java như được yêu cầu trong câu hỏi
Erin Drumond
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.