Java如何转义字符串中无匹配闭合标签的HTML标签
未闭合HTML标签识别及转义实现方案
需求匹配说明
你需要实现的效果是仅对字符串中无对应闭合标签的HTML标签做二次HTML转义,已正确配对的标签保留原有编码,和你的示例场景完全匹配:
- 输入示例:
"Its a great <strong><b>job</strong>" - 输出示例:
"Its a great <strong>&lt;b&gt;job</strong>"
核心实现逻辑
- 先对输入字符串做HTML实体解码,还原出原始
</>字符,方便识别标签结构 - 用栈结构遍历识别所有HTML标签:遇到开标签压栈,遇到匹配的闭标签弹栈,遍历结束后栈内剩余的就是未闭合标签
- 对未闭合的标签单独执行
StringEscapeUtils.escapeHtml()转义后替换回原字符串 - 最后对整体字符串做HTML实体编码,还原已配对标签的原有编码格式
Java实现代码
import org.apache.commons.text.StringEscapeUtils; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UnclosedHtmlTagHandler { // 匹配所有HTML开/闭标签的正则规则 private static final Pattern HTML_TAG_REG = Pattern.compile("<(/?[a-zA-Z][a-zA-Z0-9]*)[^>]*>"); public static String escapeUnclosedTags(String inputStr) { // 解码得到原始HTML结构 String decodedContent = StringEscapeUtils.unescapeHtml4(inputStr); Stack<String> tagStack = new Stack<>(); Matcher tagMatcher = HTML_TAG_REG.matcher(decodedContent); // 识别未闭合标签 while (tagMatcher.find()) { String fullTag = tagMatcher.group(); String tagName = tagMatcher.group(1); if (fullTag.startsWith("</")) { // 匹配到闭标签,弹出栈顶匹配的开标签 if (!tagStack.isEmpty() && tagStack.peek().equals(tagName)) { tagStack.pop(); } } else { // 开标签入栈 tagStack.push(tagName); } } // 替换未闭合标签为转义后的内容 String processedContent = decodedContent; for (String unclosedTag : tagStack) { Pattern unclosedTagReg = Pattern.compile("<" + unclosedTag + "[^>]*>"); Matcher unclosedMatcher = unclosedTagReg.matcher(processedContent); if (unclosedMatcher.find()) { String rawTag = unclosedMatcher.group(); String escapedTag = StringEscapeUtils.escapeHtml4(rawTag); processedContent = processedContent.replace(rawTag, escapedTag); } } // 编码还原整体格式 return StringEscapeUtils.escapeHtml4(processedContent); } public static void main(String[] args) { String testInput = "Its a great <strong><b>job</strong>"; String testOutput = escapeUnclosedTags(testInput); System.out.println(testOutput); // 输出结果:Its a great <strong>&lt;b&gt;job</strong> } }
依赖说明
代码用到了Apache Commons Text工具类,需要在项目中引入对应依赖,Maven坐标如下:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.10.0</version> </dependency>
扩展说明
- 如需支持自闭合标签(如
<img/>、<br/>),可在识别标签时增加判断逻辑,自闭合标签无需入栈 - 如存在标签嵌套顺序错误的场景(如
<div><span></div></span>),未匹配到的标签也会被判定为未闭合做转义处理
内容的提问来源于stack exchange,提问作者Radhika
相关产品推荐
相关产品推荐

