可以跳过HTML标记的java.io.Reader类?

可以跳过HTML标记的java.io.Reader类?,java,html,lexer,Java,Html,Lexer,我需要去除大量文本中的HTML。如果我能找到一个实现java.io.Reader的类来包装另一个阅读器,并转换文本以省略所有HTML标记(或者用空格替换它们),那就太棒了。它需要能够处理格式错误的HTML 表现很重要。我需要尽可能快地处理大量千兆字节的文本。通常的方法是将我的HTML读入字符串,解析成DOM树,然后在节点上迭代提取文本。不幸的是,这太慢了。我认为实现将必须基于某种低级lexer 有谁知道可以这样做的库吗?我过去成功地使用过 它做的比您需要的更多,因为它本质上是一个用于现实世界HT

我需要去除大量文本中的HTML。如果我能找到一个实现java.io.Reader的类来包装另一个阅读器,并转换文本以省略所有HTML标记(或者用空格替换它们),那就太棒了。它需要能够处理格式错误的HTML

表现很重要。我需要尽可能快地处理大量千兆字节的文本。通常的方法是将我的HTML读入字符串,解析成DOM树,然后在节点上迭代提取文本。不幸的是,这太慢了。我认为实现将必须基于某种低级lexer

有谁知道可以这样做的库吗?

我过去成功地使用过


它做的比您需要的更多,因为它本质上是一个用于现实世界HTML的DOM解析器。好的是它很健壮;它可以像浏览器一样处理标记中的怪癖。

为了提高速度,您可能需要流式解析器。也许吧?

我想你想要所有的文本,所以一个得到大多数东西的刻板正则表达式是不合适的。这意味着您至少需要经历解析的第一部分,但希望库在这之后尽可能少地进行解析


您可以使用它提供一个很好的低级sax接口。只需忽略标记并收集文本节点的值。简单且尽可能快。

也许ParserCallback比创建DOM快多少

import java.io.*;
import java.net.*;
import javax.swing.text.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;

public class ParserCallbackText extends HTMLEditorKit.ParserCallback
{
    public void handleText(char[] data, int pos)
    {
        System.out.println( data );
    }

    public static void main(String[] args)
        throws Exception
    {
        Reader reader = getReader(args[0]);
        ParserCallbackText parser = new ParserCallbackText();
        new ParserDelegator().parse(reader, parser, true);
    }

    static Reader getReader(String uri)
        throws IOException
    {
        // Retrieve from Internet.
        if (uri.startsWith("http:"))
        {
            URLConnection conn = new URL(uri).openConnection();
            return new InputStreamReader(conn.getInputStream());
        }
        // Retrieve from file.
        else
        {
            return new FileReader(uri);
        }
    }
}

通常的方法实际上是直接从文件解析HTML,而不是中间浪费时间和空间的字符串,但是,正如其他海报所说,您必须首先整理HTML,使用JTidy、NekoHMTL等。从那里我可能会使用XSLT,但如果需要极高的性能,则可能不会。您仍然可以选择解析器:SAX或StAX解析器将比DOM解析器更快、更节省空间。

我建议使用XSLT,但您说有些HTML格式不好,这会使事情变得复杂。您可以尝试先通过JTidy运行它,然后再应用XSLT。但是XSLT并不是非常快。你可能想考虑一个简单的选择和替换。也许你可以用一个TAG汤看起来很酷。一个缺点是,它说它不适用于JDK中的默认XML代码,您必须使用Saxon。但在其他方面看起来不错。