写一个方法检测页面中的所有标签是否正确闭合
function checkTagClosure(htmlString) {
// 使用栈来跟踪打开的标签
const tagStack = [];
// 正则表达式匹配标签 (包括自闭合标签)
const tagRegex = /<\/?([a-zA-Z][a-zA-Z0-9]*)\s*\/?>/g;
let match;
while ((match = tagRegex.exec(htmlString)) !== null) {
const tagName = match[1];
const isClosingTag = match[0].startsWith("</");
if (isClosingTag) {
// 闭合标签,检查栈顶是否匹配
if (tagStack.length === 0 || tagStack.pop() !== tagName) {
return {
isValid: false,
error: `Unexpected closing tag: ${tagName}, at index: ${match.index}`,
};
}
} else {
// 非自闭合标签,压入栈中
if (!isSelfClosingTag(tagName)) { // 检查是否为自闭合标签
tagStack.push(tagName);
}
}
}
// 检查栈是否为空,如果不为空,则存在未闭合的标签
if (tagStack.length > 0) {
return {
isValid: false,
error: `Unclosed tags: ${tagStack.join(", ")}`,
};
}
return { isValid: true };
}
function isSelfClosingTag(tagName) {
const selfClosingTags = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"];
return selfClosingTags.includes(tagName.toLowerCase());
}
// 示例用法:
const html1 = "<div><h1>Hello</h1><p>World</p></div>";
const result1 = checkTagClosure(html1);
console.log(result1); // { isValid: true }
const html2 = "<div><h1>Hello<p>World</div>";
const result2 = checkTagClosure(html2);
console.log(result2); // { isValid: false, error: "Unexpected closing tag: div, at index: 18" }
const html3 = "<div><img src='test.jpg' alt='test'></div>";
const result3 = checkTagClosure(html3);
console.log(result3); // { isValid: true }
const html4 = "<div><p>Test</div>";
const result4 = checkTagClosure(html4);
console.log(result4); // { isValid: false, error: 'Unexpected closing tag: div, at index: 10'}
const html5 = "<div><p>Test</p>";
const result5 = checkTagClosure(html5);
console.log(result5); // { isValid: false, error: 'Unclosed tags: div' }
改进和说明:
- 处理自闭合标签: 增加了
isSelfClosingTag
函数来处理自闭合标签,避免将它们误判为未闭合标签。 - 错误信息更详细: 返回的错误信息包含了未闭合或错误闭合的标签名称以及错误发生的位置索引,方便调试。
- 使用正则表达式: 使用正则表达式匹配标签,更加灵活和健壮。
- 区分大小写: 将标签名转换为小写再进行比较,避免因为大小写问题导致误判。
- 更全面的自闭合标签列表: 包含了更全面的自闭合标签列表。
这个改进后的版本可以更准确地检测 HTML 标签的闭合情况,并提供更详细的错误信息。 它仍然有一些局限性,例如无法处理复杂的嵌套情况和注释,但在大多数情况下可以有效地工作。 对于更复杂的场景,建议使用专业的 HTML 解析器。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了