Java中如何不转义现有HTML实体,仅编码特殊HTML字符
HTML特殊字符编码(不转义已有实体)实现方案
核心逻辑
StringEscapeUtils默认转义逻辑会无差别替换所有特殊字符,不会识别已存在的合法HTML实体,因此会出现过度转义问题。正确的处理逻辑如下:
- 先匹配所有合法HTML实体(包括命名实体如
<、十进制实体如<、十六进制实体如<),匹配到的部分直接保留不处理 - 仅对实体之外的普通文本中的特殊字符(
&、<、>、"、')做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("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'"); } // 测试用例 public static void main(String[] args) { String input = "<div>1 < 2</div>"; String output = escapeSpecialCharsOnly(input); // 输出结果:<div>1 &lt; 2</div>,完全符合需求 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 = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; 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 = "<div>1 < 2</div>"; console.log(escapeHtmlKeepExistingEntities(input)); // 输出结果:<div>1 &lt; 2</div>
内容的提问来源于stack exchange,提问作者lecogiteur
相关产品推荐
相关产品推荐

