在處理富文本、爬蟲數據清洗、XSS 防護等場景中,常需從字串中剝離 HTML 標籤與實體字符(如 、<),僅保留純文本內容。本文提供基於正則表達式的高效解決方案,並解析關鍵正則語法與邊界情況處理。
String cleanText = htmlString
.replaceAll("\\&[a-zA-Z]{0,9};", "") // 移除 HTML 實體字符
.replaceAll("<[^>]*>", "\n\t"); // 移除標籤,替換為換行+縮排保持可讀性
\\&[a-zA-Z]{0,9};| 片段 | 含義 |
|---|---|
\\& | 匹配字面字符 &(需雙重轉義:Java 字串 \→ 正則 \) |
[a-zA-Z] | 匹配英文字母(實體名僅含字母,如 nbsp、lt、gt、amp、copy、reg 等) |
{0,9} | 長度 0~9 位(涵蓋常見實體,最長如 &counterclockwisearrows; 等罕見長實體) |
; | 匹配結束分號 |
匹配範例: 、<、>、&、©、{ (數字實體 不匹配,見下文補充)
<[^>]*>| 片段 | 含義 |
|---|---|
< | 匹配字面 <(標籤開始) |
[^>]* | 匹配任意非 > 字符(貪婪匹配標籤內容,含屬性) |
> | 匹配字面 >(標籤結束) |
匹配範例:<div>、<a href="...">、<img src="x.jpg" alt="圖" />、</table>
替換策略:替換為 "\n\t"(換行+製表符)而非空字串,避免標籤移除後文字擠在一起(如 <td>A</td><td>B</td> 變成 AB),保留基本排版結構。
public class HtmlTagRemover {
public static void main(String[] args) {
String html = "<table border='1' cellpadding='1' cellspacing='1'>"
+ "<tr><th rowspan='2'>序號</th><th colspan='2'>李四</th><th>趙六</th></tr>"
+ "</table>";
// 執行清洗
String clean = html
.replaceAll("\\&[a-zA-Z]{0,9};", "")
.replaceAll("<[^>]*>", "\n\t");
System.out.println("=== 清洗後純文本 ===");
System.out.println(clean);
/*
輸出:
序號
李四
趙六
*/
}
}
〹 / 😀上述正則 不匹配 數字實體(十進制 &#nnnn; 或十六進制 &#xhhhh;)。若需支援,擴展正則:
// 合併匹配:命名實體 | 十進制數字實體 | 十六進制數字實體
String entityRegex = "\\&(?:[a-zA-Z]{0,9}|#[0-9]{1,5}|#x[0-9a-fA-F]{1,4});";
String clean = html.replaceAll(entityRegex, "")
.replaceAll("<[^>]*>", "\n\t");
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 正則 replaceAll | 零依賴、程式碼極簡、效能尚可 | 極複雜/異常 HTML 可能誤傷;無法處理跨行標籤嵌套邏輯 | 簡單清洗、已知格式、輕量級專案 |
Jsoup Jsoup.parse(html).text() | 標準 HTML 解析器、自動修正畸形標籤、極其健壯 | 需引入第三方依賴、物件建構開銷大 | 生產環境、複雜 HTML、安全敏感(XSS 清洗) |
| HTMLParser / Jericho | 流式解析、低記憶體 | API 複雜、維護度較低 | 大文件串流處理 |
Whitelist 白名單模式,防止 XSS 繞過正則。Pattern 物件(Pattern.compile())複用,避免重複編譯正則。<br>、</p> 等轉為 \n,而非全部替換為空格。