如何在Java中正确反转义HTML实体以匹配浏览器解析效果?
解决Java中HTML实体𝐿反转义问题
问题根源
𝐿对应Unicode U+1D43F(数学斜体大写L),属于增补平面字符(超出U+FFFF范围),部分旧版解析库无法正确处理这类字符的代理对(增补平面字符需要两个char组合表示),导致反转义后出现乱码或错误结果。
手动解析方案
直接提取实体中的十进制/十六进制编码,通过Character.toChars()转换为正确字符,该方法会自动处理增补平面的代理对问题。
代码实现
import java.util.regex.Matcher; import java.util.regex.Pattern; public class HtmlEntityDecoder { // 匹配十进制(&#数字;)和十六进制(&#x十六进制;)实体 private static final Pattern HTML_ENTITY_PATTERN = Pattern.compile("&#(?:(\\d+)|x([0-9a-fA-F]+));"); public static String decodeHtmlEntities(String input) { if (input == null || input.isEmpty()) { return input; } Matcher matcher = HTML_ENTITY_PATTERN.matcher(input); StringBuffer result = new StringBuffer(); while (matcher.find()) { int codePoint; if (matcher.group(1) != null) { // 处理十进制实体 codePoint = Integer.parseInt(matcher.group(1)); } else { // 处理十六进制实体 codePoint = Integer.parseInt(matcher.group(2), 16); } // 转换为对应字符(自动处理增补平面代理对) char[] chars = Character.toChars(codePoint); matcher.appendReplacement(result, new String(chars)); } matcher.appendTail(result); return result.toString(); } public static void main(String[] args) { String encodedStr = "测试数学斜体L:𝐿 或 𝐿"; String decodedStr = decodeHtmlEntities(encodedStr); System.out.println(decodedStr); // 输出:测试数学斜体L:𝐿 或 𝐿 } }
与现有库结合使用
如果字符串中还包含其他HTML命名实体(比如&、<),可以先用成熟库(如Apache Commons Lang、Jsoup)处理这些常规实体,再用上述方法处理特殊的增补平面实体:
// 示例:先用Jsoup处理普通实体,再处理特殊实体 String rawStr = "混合内容:<数学符号𝐿>"; String tempDecoded = Jsoup.parse(rawStr).text(); String finalDecoded = HtmlEntityDecoder.decodeHtmlEntities(tempDecoded);
内容的提问来源于stack exchange,提问作者Hevv
相关产品推荐
相关产品推荐

