You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何不转义现有HTML实体,仅编码特殊HTML字符

HTML特殊字符编码(不转义已有实体)实现方案

核心逻辑

StringEscapeUtils默认转义逻辑会无差别替换所有特殊字符,不会识别已存在的合法HTML实体,因此会出现过度转义问题。正确的处理逻辑如下:

  1. 先匹配所有合法HTML实体(包括命名实体如<、十进制实体如<、十六进制实体如<),匹配到的部分直接保留不处理
  2. 仅对实体之外的普通文本中的特殊字符(&、<、>、"、')做HTML编码转换

Java 实现方案

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CustomHtmlEscaper {
    // 匹配合法HTML实体的正则规则
    private static final Pattern HTML_ENTITY_PATTERN = Pattern.compile(
        "&(?:[a-zA-Z][a-zA-Z0-9]*|#\\d+|#x[0-9a-fA-F]+);"
    );

    public static String escapeSpecialCharsOnly(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        Matcher matcher = HTML_ENTITY_PATTERN.matcher(input);
        StringBuffer result = new StringBuffer();
        int lastProcessedPos = 0;
        
        while (matcher.find()) {
            // 处理两个实体之间的普通文本片段
            String plainText = input.substring(lastProcessedPos, matcher.start());
            result.append(escapePlainText(plainText));
            // 直接保留原有实体
            result.append(matcher.group());
            lastProcessedPos = matcher.end();
        }
        
        // 处理最后一段剩余普通文本
        result.append(escapePlainText(input.substring(lastProcessedPos)));
        return result.toString();
    }

    // 仅转义普通文本中的HTML特殊字符
    private static String escapePlainText(String text) {
        if (text == null || text.isEmpty()) {
            return text;
        }
        return text.replace("&", "&amp;")
                   .replace("<", "&lt;")
                   .replace(">", "&gt;")
                   .replace("\"", "&quot;")
                   .replace("'", "&#39;");
    }

    // 测试用例
    public static void main(String[] args) {
        String input = "&lt;div&gt;1 &lt; 2&lt;/div&gt;";
        String output = escapeSpecialCharsOnly(input);
        // 输出结果:&lt;div&gt;1 &amp;lt; 2&lt;/div&gt;,完全符合需求
        System.out.println(output);
    }
}

JavaScript 实现方案

function escapeHtmlKeepExistingEntities(input) {
    if (!input) return input;
    const entityReg = /&(?:[a-zA-Z][a-zA-Z0-9]*|#\d+|#x[0-9a-fA-F]+);/g;
    const escapeMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;'
    };
    let result = '';
    let lastIndex = 0;

    input.replace(entityReg, (match, currentIndex) => {
        // 转义实体之前的普通文本
        const plainText = input.slice(lastIndex, currentIndex);
        result += plainText.replace(/[&<>"']/g, char => escapeMap[char]);
        // 保留原有实体
        result += match;
        lastIndex = currentIndex + match.length;
        return match;
    });

    // 转义最后剩余的普通文本
    result += input.slice(lastIndex).replace(/[&<>"']/g, char => escapeMap[char]);
    return result;
}

// 测试用例
const input = "&lt;div&gt;1 < 2&lt;/div&gt;";
console.log(escapeHtmlKeepExistingEntities(input));
// 输出结果:&lt;div&gt;1 &amp;lt; 2&lt;/div&gt;

内容的提问来源于stack exchange,提问作者lecogiteur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:12:01