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

Java如何转义字符串中无匹配闭合标签的HTML标签

未闭合HTML标签识别及转义实现方案

需求匹配说明

你需要实现的效果是仅对字符串中无对应闭合标签的HTML标签做二次HTML转义,已正确配对的标签保留原有编码,和你的示例场景完全匹配:

  • 输入示例:"Its a great <strong><b>job</strong>"
  • 输出示例:"Its a great <strong><b>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 &lt;strong&gt;&lt;b&gt;job&lt;/strong&gt;";
        String testOutput = escapeUnclosedTags(testInput);
        System.out.println(testOutput);
        // 输出结果:Its a great &lt;strong&gt;&amp;lt;b&amp;gt;job&lt;/strong&gt;
    }
}

依赖说明

代码用到了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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:09:03