富文本編輯器輸出、爬蟲擷取內容、前端 XSS 防護等場景,需移除 HTML 標籤並解碼實體字元(如 、<)。
// 1. 移除實體字元 &xxx;
str = str.replaceAll("&[a-zA-Z]{1,10};", "");
// 2. 移除所有標籤 <...>
str = str.replaceAll("<[^>]*>", "");
// 3. 合併寫法
str = str.replaceAll("&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "");
public class HtmlCleaner {
private static final Pattern ENTITY_PATTERN = Pattern.compile("&[a-zA-Z]{1,10};|\\d{1,5};|[0-9a-fA-F]{1,4};");
private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>", Pattern.DOTALL);
/** 移除標籤與實體,保留純文字,標籤間換行 */
public static String clean(String html) {
if (html == null) return "";
String text = ENTITY_PATTERN.matcher(html).replaceAll("");
text = TAG_PATTERN.matcher(text).replaceAll("\n");
// 壓縮多餘空白行
return text.replaceAll("\\n{3,}", "\n\n").trim();
}
/** 移除指定標籤 (如 script, style) 及其內容 */
public static String removeTags(String html, String... tagNames) {
if (html == null || tagNames.length == 0) return html;
StringBuilder regex = new StringBuilder("(?is)<(");
for (int i = 0; i < tagNames.length; i++) {
if (i > 0) regex.append('|');
regex.append(Pattern.quote(tagNames[i]));
}
regex.append(")\\b[^>]*>.*?").append(tagNames[0]).append(">");
// 簡化:實際需為每個標籤構建獨立正則
return html.replaceAll(regex.toString(), "");
}
}
public static void main(String[] args) {
String html = "\n" +
" 標題 & 子標題
\n" +
" 內容 包含 實體
\n" +
" \n" +
"";
System.out.println(HtmlCleaner.clean(html));
}
標題 子標題
內容 包含 實體
alert('xss')
| 庫 | 特點 |
|---|---|
| Jsoup | Jsoup.clean(html, Whitelist.none()) 白名單機制,防 XSS 業界標準 |
| HtmlCleaner | DOM 解析,容錯性強,可輸出 XML |
| OWASP Java HTML Sanitizer | 專注 XSS 防護,效能高,Google 維護 |
>、CDATA、註解等複雜結構。