Удалить теги HTML из строки

К сожалению, у меня нет достаточного количества баллов, чтобы опубликовать это как комментарий к принятому ответу ... Я скорректировал код в соответствии со своей собственной задачей, требующей интерполяции на одноканальной матрице поплавков.

Я думал, что мне хотелось бы, чтобы какая-то интуиция о том, какой из подходов является самым быстрым.

Я реализовал 3 метода из ответа Андрея Камаева, а также простого ближайшего соседа (в основном просто округляя координаты ).

Я провел эксперимент с матрицей A (100x100), которую я просто заполнил мусором. Затем я сделал матрицу B (400x400), которая заполнена значениями, интерполированными из a такими, что: B (i, j) = A (i / 4, j / 4).

Каждый прогон был выполнен 1000 и среднее время:

  • Ближайший сосед: 2.173 мс
  • getRectSubPix: 26.506 ms
  • remap: 114.265 ms
  • : 5.086 ms
  • руководство без borderInterpolate: 3.842 ms

Так что ближайший сосед для сверхскоростной скорости, если вы действительно не слишком заботитесь об актуальной интерполяции и просто нужно значение - особенно если ваши данные изменяются очень плавно. Для всего остального я бы пошел с ручной билинейной интерполяцией, поскольку он кажется последовательно быстрее других методов. (OpenCV 2.4.9 - Ubuntu 15.10 Repo - февраль 2016).

Если вы знаете все 4, ваш вкладчик находится в пределах вашей матрицы, тогда вы можете сделать его в основном эквивалентным во времени ближайшему соседству - хотя разница все равно незначительна.

403
задан dimo414 24 June 2016 в 03:13
поделиться

9 ответов

Использовать синтаксический анализатор HTML вместо регулярного выражения. Это очень просто с Jsoup .

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

Jsoup также поддерживает удаление HTML-тегов из настраиваемого белого списка, что очень полезно, если вы хотите разрешить только, например, , и .

См. Также:

547
ответ дан 22 November 2019 в 23:32
поделиться

Иначе должен использовать 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-тэги из файла для извлечения только ТЕКСТА

28
ответ дан CSchulz 24 June 2016 в 03:13
поделиться

Это кажется, что Вы хотите пойти от 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;
}
3
ответ дан CSchulz 24 June 2016 в 03:13
поделиться

Выход HTML действительно трудно сделать правильно - я определенно предложил бы использовать код библиотеки, чтобы сделать это, поскольку это намного более тонко, чем Вы думали бы. Проверьте Apache StringEscapeUtils для довольно хорошей библиотеки для обработки этого в Java.

12
ответ дан nico.ruti 24 June 2016 в 03:13
поделиться

Если пользователь входит <b>hey!</b>, Вы хотите отобразиться <b>hey!</b> или hey!? Если первое, выйдите из меньше-thans, и HTML - кодирует амперсанды (и дополнительно заключает в кавычки), и Вы в порядке. Модификация к Вашему коду для реализации второй опции была бы:

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

, но Вы столкнетесь с проблемами, если пользователь введет что-то уродливое, как <bhey!</b>.

можно также проверить JTidy, который проанализирует "грязный" ввод HTML и должен дать Вам способ удалить теги, сохранив текст.

проблема с попыткой разделить HTML состоит в том, что браузеры имеют очень снисходительные синтаксические анализаторы, более снисходительные, чем какая-либо библиотека, которую можно найти, будет, поэтому даже если Вы приложите все усилия для разделения всех тегов (использующий метод замены выше, библиотека DOM или JTidy), Вы будете все еще потребность удостовериться, что закодировали любые остающиеся специальные символы HTML для защиты вывода.

78
ответ дан Chris Marasti-Georg 24 June 2016 в 03:13
поделиться

Вы могли бы хотеть заменить <br/> и </p> теги с новыми строками прежде, чем разделить HTML для предотвращения его становящийся неразборчивой путаницей, как Tim предполагает.

единственный способ, которым я могу думать об удалении HTML-тэгов, но отъезд не-HTML между угловыми скобками был бы проверкой по сравнению с список HTML-тэгов . Что-то вдоль этих строк...

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

Тогда декодируют HTML специальные символы такой как &amp;. Результат не должен считаться санированным.

6
ответ дан foxy 24 June 2016 в 03:13
поделиться
  • 1
    нет это должно работать. Проверьте однажды useing desc, если это там. Попытайтесь перезапустить mysql однажды. Но это должно работать. – A Paul 4 February 2014 в 11:55

Вот несколько более подробное обновление, чтобы попытаться обработать некоторое форматирование для разрывов и списков. Я использовал вывод Amaya в качестве руководства.

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
ответ дан 22 November 2019 в 23:32
поделиться

Еще одним способом может быть использование класса com.google.gdata.util.common.html.HtmlToText например

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

Однако это не пуленепробиваемый код, и когда я запускаю его для записей в Википедии, я получаю информацию о стиле. Однако я считаю, что для небольших/простых задач это будет эффективно.

3
ответ дан 22 November 2019 в 23:32
поделиться

Принятый ответ не сработал для указанного мной тестового случая: результатом "a < b или b > c" является "a b или b > c".

Поэтому вместо него я использовал 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 {
}
}
4
ответ дан 22 November 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: