首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 移除 HTML 標籤的正則與 Jsoup 方案對比:從簡單替換到安全清洗

     編輯:Java 相關知識

前言

在 Java 中移除 HTML 標籤是常見需求 (如摘要生成、XSS 防禦、文本提取)。最直觀的方法是正則表達式替換,但 **HTML 不是正則語言**,複雜巢狀結構、屬性值包含 `>`、註釋、CDATA、腳本樣式標籤等場景極易導致正則失效或災難性回溯。本文對比正則方案與業界標準庫 **Jsoup** 的優劣,給出生產環境建議。

方案一:正則表達式 (僅適用極簡單、可控輸入)

public class RegexHtmlStripper {
    // 簡單移除標籤:<...> 替換為空格/換行
    private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>", Pattern.DOTALL);
    // 移除 HTML 實體:  < 等
    private static final Pattern ENTITY_PATTERN = Pattern.compile("&[a-zA-Z]{1,10};|&#\\d{1,5};|&#x[0-9a-fA-F]{1,4};");

    public static String stripTags(String html) {
        if (html == null) return "";
        String text = TAG_PATTERN.matcher(html).replaceAll(" "); // 標籤轉空格保留詞邊界
        text = ENTITY_PATTERN.matcher(text).replaceAll("");      // 移除實體
        // 壓縮多餘空白
        return text.replaceAll("\\s+", " ").trim();
    }

    public static void main(String[] args) {
        String html = "
IDName
1Alice
"; System.out.println(stripTags(html)); // 輸出: ID Name 1 Alice } }

正則方案的致命缺陷

場景正則行為風險
屬性值含 `>``
` 被錯誤截斷
殘留標籤碎片
註釋 ``正則 `<[^>]*>` 無法跨行匹配 ``註釋內容洩露
腳本/樣式內容`` 內部 `<` `>` 干擾匹配JS/CSS 代碼洩露
CDATA 區段`]]>` 被誤當標籤文本損壞
惡意輸入`<<<` 繞過簡單過濾XSS 攻擊
災難性回溯`<[^>]*>` 遇超長無 `>` 字符串CPU 100% 拒絕服務

方案二:Jsoup — 專業 HTML 解析器 (強烈推薦生產環境)

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.17.2</version>
</dependency>
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Safelist;

public class JsoupHtmlProcessor {

    // 1. 純文本提取 (保留可見文本結構)
    public static String extractText(String html) {
        if (html == null) return "";
        // parse() 自動修補不完整 HTML,body() 獲取 body 內容
        return Jsoup.parse(html).body().text(); 
    }

    // 2. 安全清洗:只保留白名單標籤/屬性 (防 XSS)
    public static String cleanHtml(String html, Safelist safelist) {
        if (html == null) return "";
        return Jsoup.clean(html, safelist);
    }

    // 3. 移除所有標籤但保留換行結構 (模擬瀏覽器渲染文本)
    public static String stripTagsKeepStructure(String html) {
        if (html == null) return "";
        Document doc = Jsoup.parse(html);
        // 移除 script, style, noscript 等非可見標籤及其內容
        doc.select("script, style, noscript, iframe, object, embed").remove();
        // 將塊級標籤轉為換行
        doc.select("div, p, br, h1, h2, h3, h4, h5, h6, li, tr, td, th, table, ul, ol").append("\\n");
        return doc.body().text().replaceAll("\\n+", "\\n").trim();
    }

    public static void main(String[] args) {
        String dirty = "

Hello World

Link
"; System.out.println("--- 純文本 ---"); System.out.println(extractText(dirty)); // 輸出: Hello World Link System.out.println("--- 安全清洗 (基本標籤) ---"); System.out.println(cleanHtml(dirty, Safelist.basic())); // 輸出:

Hello World

Link (移除 script, 注釋, 危險 href) System.out.println("--- 保留結構文本 ---"); System.out.println(stripTagsKeepStructure(dirty)); // 輸出帶換行的純文本 } }

Jsoup 核心優勢

  • 標準解析器:基於 HTML5 規範,正確處理巢狀、自閉合、錯誤修補。
  • XSS 防禦:`Safelist` (原 `Whitelist`) 提供 `basic()`, `simpleText()`, `relaxed()`, `none()` 等預設策略,可自定義標籤/屬性/協議白名單。
  • 選擇器 API:類 jQuery 的 `doc.select("div.content > p")` 強大查詢。
  • 效能:單次解析樹遍歷,避免正則回溯,大文檔穩定高效。

選型決策表

需求場景推薦方案理由
用戶輸入富文本存儲/展示 (CMS、評論、郵件)Jsoup.clean(html, Safelist.relaxed())安全第一,保留排版能力
搜索摘要、關鍵字提取、純文本索引Jsoup.parse(html).text()完整提取可見文本,忽略腳本樣式
極簡模板、固定格式、高效能、無用戶輸入預編譯正則零依賴、極快,但需嚴格測試輸入範圍
移除特定標籤 (如所有 ``)Jsoup: doc.select("font").unwrap()結構化操作,不破壞巢狀

總結

**正則表達式無法可靠解析 HTML。** 除非輸入極其簡單且完全可控 (如系統生成的固定模板),**生產環境請無腦使用 Jsoup**。它不僅能提取文本,更是防禦 XSS、清洗富文本的標準利器。引入一個 300KB 的 JAR,換來的是安全、正確、可維護的代碼,極具性價比。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved