سؤال

هل هناك طريقة جيدة لإزالة HTML من جافا السلسلة ؟ بسيطة مثل regex

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

سوف تعمل ، ولكن أشياء مثل &amp; لن يتم تحويلها بشكل صحيح وغير HTML بين أقواس زاوية سيتم إزالة (أيعلى .*? في regex سوف تختفي).

هل كانت مفيدة؟

المحلول

استخدام محلل HTML بدلا من regex.هذا هو الميت بسيطة مع Jsoup.

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

Jsoup أيضا يدعم إزالة علامات HTML ضد القائمة البيضاء للتخصيص ، وهو أمر مفيد جدا إذا كنت تريد أن تسمح فقط على سبيل المثال <b>, <i> و <u>.

انظر أيضا:

نصائح أخرى

إذا كنت تكتب عن الروبوت يمكنك أن تفعل هذا...

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

إذا يدخل المستخدم <b>hey!</b>، هل تريد عرض <b>hey!</b> أو hey!؟ إذا كان الأول، والهروب أقل thans، والوات أتش تي أم أل ترميز (ونقلت اختياريا) وأنت بخير. ومن شأن تعديل التعليمات البرمجية لتنفيذ الخيار الثاني:

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

ولكن سوف تصل الى القضايا إذا قام المستخدم بإدخال شيء تالف، مثل <bhey!</b>.

ويمكنك أيضا إجراء فحص JTidy التي سوف تحليل "القذرة" إدخال أتش تي أم أل، وينبغي أن تعطيك الطريق لإزالة العلامات، والحفاظ على النص.

والمشكلة مع محاولة لتجريد أتش تي أم أل هي أن برامج التصفح لديك موزعي متساهلة جدا، أكثر تساهلا من أي مكتبة يمكنك العثور صح التعبير، لذلك حتى لو أن تبذل قصارى جهدك لتجريد جميع العلامات (باستخدام طريقة استبدال أعلاه، مكتبة DOM، أو JTidy)، سوف <م> لا تزال بحاجة للتأكد من لترميز أية أحرف خاصة HTML المتبقية على ابقاء الانتاج الخاصة بك آمنة.

وهناك طريقة أخرى لاستخدام <م> javax.swing.text.html.HTMLEditorKit لاستخراج النص.

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

المرجع: إزالة علامات HTML من ملف لاستخراج فقط TEXT

وأعتقد أن simpliest لطريقة لتصفية علامات HTML هي:

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

وأيضا بسيط جدا باستخدام أريحا ، ويمكنك الاحتفاظ ببعض التنسيق (الخط فواصل والروابط، على سبيل المثال).

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

في الروبوت، حاول هذا:

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

وHTML الهروب من الصعب حقا القيام به اليمين كنت تشير بالتأكيد باستخدام رمز مكتبة للقيام بذلك، كما انها أكثر بكثير مكرا مما كنت اعتقد. تحقق من أباتشي StringEscapeUtils لمكتبة جيدة للتعامل مع هذا في جاوة.

الجواب المقبول القيام ببساطة Jsoup.parse(html).text() 2 المحتملة المسائل (مع JSoup 1.7.3):

  • فإنه يزيل فواصل أسطر من النص
  • فإنه يحول النص &lt;script&gt; في <script>

إذا كنت تستخدم هذا لحماية ضد XSS, هذا هو مزعج قليلا.هنا هو بلدي أفضل لقطة في تحسين الحل باستخدام كل JSoup أباتشي 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);

علما أن الخطوة الأخيرة لأنني بحاجة إلى استخدام الإخراج كما نص عادي.إذا كنت بحاجة فقط إخراج HTML ثم يجب أن تكون قادرة على إزالته.

و هنا مجموعة من حالات الاختبار (المدخلات والمخرجات):

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

إذا كنت تجد طريقة لجعله أفضل ، يرجى اسمحوا لي أن أعرف.

وقد ترغب في استبدال علامات <br/> و</p> مع أسطر جديدة قبل تجريد HTML لمنع أن يصبح فوضى غير مقروء كما يقترح تيم.

والطريقة الوحيدة التي يمكنني أن أفكر في إزالة علامات HTML لكنه ترك غير HTML بين أقواس زاوية سيكون تحقق ضد <لأ href = "http://www.w3schools.com/tags/default.asp" يختلط = " noreferrer "> قائمة العلامات HTML . شيء على طول هذه الخطوط ...

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

وبعد ذلك HTML-فك أحرف خاصة مثل &amp;. لا ينبغي اعتبار النتيجة إلى أن مطهرة.

وهذا يجب أن تعمل -

استخدم هذا

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

وهذا

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

والجواب المقبول لم تنجح بالنسبة لي لحالة اختبار أشرت: نتيجة "ل<ب أو ب> ج" هو "أ ب أو ب> ج"

.

وهكذا، كنت TagSoup بدلا من ذلك. وهنا لقطة التي عملت لحالتي اختبار (واثنين آخرين):

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

وأعرف أن هذا هو القديم، ولكن كنت أعمل فقط على المشروع الذي يتطلب مني لتصفية HTML وهذا يعمل على ما يرام:

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

وبدلا من هذا:

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

وفيما يلي طفيفة أكثر بلورتها التحديث لمحاولة التعامل مع بعض التنسيق للفواصل والقوائم. اعتدت الانتاج أمايا كدليل.

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

وبدلا من ذلك، يمكن للمرء أن استخدام HtmlCleaner :

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

استخدام Html.fromHtml

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>

كما في الروبوت الوثائق الرسمية أي فئة في HTML كما سيتم عرض عام الاستبدال سلسلة وهو البرنامج الخاص بك ثم يمكن أن تذهب من خلال استبدال مع ريال مدريد سلاسل.

Html.formHtml الأسلوب يأخذ Html.TagHandler و Html.ImageGetter كما الحجج فضلا عن النص إلى تحليل.

على سبيل المثال

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

ثم

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

الإخراج

هذا هو عني نص يمكن للمستخدم وضع في ملفه الشخصي

واحد بطريقة أكثر يمكن أن يكون لاستخدام الطبقة com.google.gdata.util.common.html.HtmlToText مثل

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

وهذه ليست رصاصة كود برهان على الرغم من وعندما تشغيلها على مداخل ويكيبيديا أنا على الحصول على معلومات النمط أيضا. ومع ذلك أعتقد عن وظائف صغيرة / بسيطة هذا من شأنه أن يكون فعالا.

ويبدو أنك تريد أن تذهب من HTML إلى نص عادي.
إذا كان هذا هو الحال في نظرة www.htmlparser.org. هنا هو مثال يجرد جميع العلامات الخروج من ملف HTML وجدت في URL.
فإنه يجعل من استخدام <م> org.htmlparser.beans.StringBean .

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

وهنا هو طريقة أخرى للقيام بذلك:

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

وهنا هو واحد أكثر البديل من كيفية استبدال جميع (HTML الكلمات | الكيانات HTML | الفضاء الخالي في محتوى HTML)

وcontent.replaceAll("(<.*?>)|(&.*?;)|([ ]{2,})", ""); حيث المحتوى هو سلسلة.

واحد ويمكن أيضا استخدام أباتشي تيكا لهذا الغرض. افتراضيا أنه يحفظ الفراغات من أتش تي أم أل تجريد، والتي قد تكون المطلوب في حالات معينة:

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

وطريقة واحدة للاحتفاظ معلومات خط جديد مع JSoup هي ان تسبق كل بطاقة خط جديدة مع بعض سلسلة وهمية، وتنفيذ JSoup واستبدال سلسلة وهمية مع "\ ن".

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

يمكنك ببساطة استخدام الافتراضي الروبوت تصفية HTML

    public String htmlToStringFilter(String textToFilter){

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

    }

الطريقة المذكورة أعلاه سوف يعود HTML تصفيتها سلسلة المدخلات الخاصة بك.

وبلدي 5 سنتات:

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

للحصول على formateed عادي نص html يمكنك أن تفعل ذلك:

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

للحصول على formateed نص عادي تغيير <br /> بواسطة و تغيير السطر الأخير من قبل:

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

ويمكنك ببساطة جعل الأسلوب مع replaceAll متعددة () مثل

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

استخدم هذا الرابط لاستبدال الأكثر شيوعا التي تحتاج إليها: http://tunes.org/wiki/html_20special_20characters_20and_20symbols.html

وانها بسيطة لكنها فعالة. يمكنني استخدام هذه الطريقة لأول مرة لإزالة غير المرغوب فيه ولكن ليس السطر الأول جدا أي replaceAll ( "\ <. *؟>"، "")، وبعد ذلك يمكنني استخدام كلمات محددة للبحث عن مؤشرات وثم استخدام .substring (بداية، نهاية ) طريقة لتجريد بعيدا الاشياء غير الضرورية. لأن هذا هو أكثر قوة ويمكنك دبوس نقطة بالضبط ما تحتاجه في صفحة HTML بأكملها.

وإزالة علامات HTML من السلسلة. في مكان ما نحتاج إلى تحليل بعض سلسلة التي يتم تلقيها من قبل بعض الردود مثل Httpresponse من الخادم.

لذلك نحن بحاجة إلى تحليل ذلك.

وهنا سوف تظهر كيفية إزالة علامات HTML من السلسلة.

    // 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top