JEditorPaneHTMLEditorKitParserText文本处理

wen java案例 4

本文目录导读:

JEditorPaneHTMLEditorKitParserText文本处理

  1. 核心概念说明
  2. 常见场景:提取纯文本(从 HTML 中剥离标签)
  3. 常见场景:在 JEditorPane 中显示 HTML 并获取选中文本
  4. 常见问题与注意事项
  5. 进阶:使用 Jsoup 替代(推荐用于复杂文本提取)

针对你提到的关键词组合 JEditorPaneHTMLEditorKitParserText文本处理,这通常涉及在 Java Swing 中使用 JEditorPane 搭配 HTMLEditorKit 来解析和显示 HTML 内容,或者提取其中的纯文本。

下面整理了关于这三个核心组件的场景说明、常见问题及代码示例。

核心概念说明

  • JEditorPane:Swing 中的一个文本组件,可以显示纯文本、HTML 和 RTF 格式。
  • HTMLEditorKit:负责解析和编辑 HTML 内容的编辑器工具包,它是 JEditorPane 显示 HTML 的核心。
  • Parser / ParserCallbackHTMLEditorKit 内部使用 javax.swing.text.html.parser.ParserDelegator 来解析 HTML,你可以通过自定义 HTMLEditorKit.ParserCallback 来拦截解析过程中的各种 HTML 标签和文本,从而提取纯文本或进行自定义处理。

常见场景:提取纯文本(从 HTML 中剥离标签)

这是最常见的需求,使用 HTMLEditorKitParserDelegator 配合 ParserCallback 实现。

代码示例:从 HTML 字符串中提取纯文本

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import java.io.IOException;
import java.io.StringReader;
public class HtmlToPlainTextExtractor {
    public static String extractText(String html) throws IOException {
        if (html == null || html.isEmpty()) {
            return "";
        }
        final StringBuilder text = new StringBuilder();
        // 1. 创建 ParserCallback
        HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback() {
            @Override
            public void handleText(char[] data, int pos) {
                // 每当解析到文本节点时,追加到 StringBuilder
                text.append(data);
            }
            @Override
            public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
                // 处理开始标签,例如遇到 <br> 或 <p> 时添加换行
                if (t == HTML.Tag.BR || t == HTML.Tag.P || t == HTML.Tag.DIV || t == HTML.Tag.LI) {
                    text.append('\n');
                }
            }
            @Override
            public void handleEndTag(HTML.Tag t, int pos) {
                // 处理结束标签,如 </p>、</div> 后加换行
                if (t == HTML.Tag.P || t == HTML.Tag.DIV || t == HTML.Tag.H1 || t == HTML.Tag.H2
                        || t == HTML.Tag.H3 || t == HTML.Tag.H4 || t == HTML.Tag.H5 || t == HTML.Tag.H6
                        || t == HTML.Tag.LI) {
                    text.append('\n');
                }
            }
            @Override
            public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
                // 处理自闭合标签,如 <br/>、<hr/>
                if (t == HTML.Tag.BR) {
                    text.append('\n');
                } else if (t == HTML.Tag.HR) {
                    text.append("\n---\n");
                }
            }
            @Override
            public void handleComment(char[] data, int pos) {
                // 忽略注释,不处理
            }
            @Override
            public void handleError(String errorMsg, int pos) {
                // 可以记录日志,但通常忽略解析错误
                System.err.println("HTML Parse error at " + pos + ": " + errorMsg);
            }
        };
        // 2. 创建解析器并解析
        ParserDelegator parser = new ParserDelegator();
        // 注意:StringReader 需要包装
        try (StringReader reader = new StringReader(html)) {
            // 第三个参数用于 Strict/Transitional 模式,通常设为 true
            parser.parse(reader, callback, true);
        }
        return text.toString().trim();
    }
    public static void main(String[] args) throws IOException {
        String html = "<html><body><h1>Title</h1><p>This is <b>bold</b> and <i>italic</i> text.</p><br/>Line 2<br>Line 3<ul><li>Item 1</li><li>Item 2</li></ul></body></html>";
        String plainText = extractText(html);
        System.out.println("=== Plain Text ===");
        System.out.println(plainText);
        // 期望输出:
        // Title
        // This is bold and italic text.
        // Line 2
        // Line 3
        // Item 1
        // Item 2
    }
}

常见场景:在 JEditorPane 中显示 HTML 并获取选中文本

如果你已经在界面上使用 JEditorPane 显示 HTML,并希望获取用户选中的纯文本。

代码示例:从 JEditorPane 获取选中文本(纯文本)

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
public class JEditorPaneDemo {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("JEditorPane HTML Demo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(600, 400);
            // 1. 创建 JEditorPane 并设置 HTMLEditorKit
            JEditorPane editorPane = new JEditorPane();
            editorPane.setEditorKit(new HTMLEditorKit());
            editorPane.setText("<html><body><b>Bold</b> and <i>Italic</i> text.<br/><a href='#'>Click me</a></body></html>");
            editorPane.setEditable(false); // 通常作为显示组件
            // 2. 获取选中文本 (纯文本,无标签)
            JButton getSelectedButton = new JButton("Get Selected Text");
            getSelectedButton.addActionListener(e -> {
                String selectedText = editorPane.getSelectedText();
                // 注意:getSelectedText() 默认返回的是去掉 HTML 标签的纯文本
                // 但如果需要更干净的文本,可能需要手动解析
                JOptionPane.showMessageDialog(frame, "Selected: '" + selectedText + "'");
            });
            frame.setLayout(new BorderLayout());
            frame.add(new JScrollPane(editorPane), BorderLayout.CENTER);
            frame.add(getSelectedButton, BorderLayout.SOUTH);
            frame.setVisible(true);
        });
    }
}

注意:

  • editorPane.getSelectedText() 返回的是视图渲染后的文本(即去掉了标签,保留了格式后的视觉效果)。
  • 如果你需要提取整个文档的纯文本(类似上面的 extractText 方法),JEditorPane 本身没有直接提供一个方法,你需要用 Document 配合 EditorKit 来实现,或者直接使用上面的解析器方法。

常见问题与注意事项

  • 解析器线程安全ParserDelegator 不是线程安全的,不要在多个线程中同时解析。
  • 性能问题:解析大段 HTML 可能会消耗较多 CPU,建议在后台线程中执行解析操作。
  • 不完整的 HTMLHTMLEditorKit 的解析器比较宽容,能处理一些不规范的 HTML,但复杂的现代页面(如包含 JavaScript、CSS 复杂布局)效果有限。
  • 编码问题:确保输入字符串的编码正确,防止中文乱码。
  • 依赖HTMLEditorKit 是 Java SE 自带的,无需额外引入第三方库,如果需要更强大的 HTML 处理(如 XHTML、严格语法、CSS 选择器),建议使用第三方库如 Jsoup(功能更强、更简单)。

进阶:使用 Jsoup 替代(推荐用于复杂文本提取)

如果你不局限于 Swing 组件,只是想从 HTML 中提取纯文本,Jsoup 是最优雅的选择。

// 需要添加依赖:org.jsoup:jsoup:1.17.2
import org.jsoup.Jsoup;
public class JsoupExtractor {
    public static String extractText(String html) {
        if (html == null || html.isEmpty()) return "";
        // Jsoup.parse 自动处理标签剥离,jsoup 的 text() 方法自动加空格分隔
        return Jsoup.parse(html).text();
    }
    public static void main(String[] args) {
        String html = "<div>Hello <b>World</b>! <ul><li>Item 1</li><li>Item 2</li></ul></div>";
        System.out.println(JsoupExtractor.extractText(html));
        // 输出: "Hello World! Item 1 Item 2"
    }
}
  • 在 Swing 中显示 HTML -> 使用 JEditorPane + HTMLEditorKit
  • 从 HTML 中提取纯文本(自定义) -> 使用 ParserDelegator + ParserCallback
  • 从 HTML 中提取纯文本(推荐第三方) -> 使用 Jsoup,代码更简洁,解析更健壮。
  • 获取 JEditorPane 中选中的纯文本 -> editorPane.getSelectedText()

如果你有具体的代码报错或需要处理某种特定格式的 HTML(如表格、嵌套标签),欢迎提供更多细节,我可以给出更精准的示例。

抱歉,评论功能暂时关闭!