在HTML标签验证逻辑中加入锚点标签验证的实现问题
解决HTML标签匹配验证中带属性锚点标签的误判问题
我编写了一段用于检查字符串中HTML标签开闭是否匹配的代码,能正确识别<i>hello<i>这类缺少闭合标签的错误,但在处理带属性的锚点标签时会误判——比如格式正确的<a href=https://example.com>Website</a>,会被错误判定为标签不匹配。
原代码
var errMsg = ""; var message = ""; var text = "<a href=https://example.com>Website</a>" var regex = /<[^>]+>/g; var foundArr = text.match(regex); var size = foundArr.length; var reset = false; for (var i = 0; i <= size; i++) { if (reset) { i = 0; } reset = false; var arr1 = foundArr[i] + ""; if (arr1.indexOf("/>") >= 0) { foundArr.splice(foundArr.indexOf(arr1), 1); reset = true; continue; } else { var words = arr1.split('<'); var x = '</' + words[1]; for (var j = i + 1; j < foundArr.length; j++) { var arr2 = foundArr[j]; if (x == arr2) { foundArr.splice(foundArr.indexOf(arr1), 1); foundArr.splice(foundArr.indexOf(arr2), 1); reset = true; break; } } } size = foundArr.length; } if (foundArr.length > 0) { message = "<li>" + "The text has invalid tags: " + foundArr.toString().replace(/</g, "").replace(/>/g, "") + " </li>"; } console.log(message)
问题根源
原代码生成闭合标签时,直接将起始标签中<后面的全部内容拼接成</xxx>,比如对于<a href=https://example.com>,会生成</a href=https://example.com>,但实际对应的闭合标签是</a>,自然匹配失败,导致误判。
修改后的代码
var errMsg = ""; var message = ""; var text = "<a href=https://example.com>Website</a>"; // 匹配所有HTML标签的正则 var regex = /<[^>]+>/g; var foundArr = text.match(regex); var size = foundArr ? foundArr.length : 0; var reset = false; // 提取标签名的正则:匹配起始标签中的标签名称(忽略属性) var tagNameRegex = /<([a-z]+)\b[^>]*>/i; // 匹配闭合标签的正则 var closingTagRegex = /<\/([a-z]+)>/i; while (foundArr && foundArr.length > 0) { reset = false; for (var i = 0; i < foundArr.length; i++) { var currentTag = foundArr[i]; // 处理自闭合标签(如<br/>) if (currentTag.indexOf("/>") >= 0) { foundArr.splice(i, 1); reset = true; break; } // 检查是否是起始标签 var tagMatch = currentTag.match(tagNameRegex); if (tagMatch) { var tagName = tagMatch[1].toLowerCase(); // 寻找对应的闭合标签 var closingTag = "</" + tagName + ">"; for (var j = i + 1; j < foundArr.length; j++) { var closingMatch = foundArr[j].match(closingTagRegex); if (closingMatch && closingMatch[1].toLowerCase() === tagName) { // 找到匹配的闭合标签,移除两者 foundArr.splice(j, 1); foundArr.splice(i, 1); reset = true; break; } } if (reset) break; } } if (!reset) break; // 没有可移除的标签对,退出循环 } if (foundArr && foundArr.length > 0) { message = "<li>" + "The text has invalid tags: " + foundArr.toString().replace(/</g, "").replace(/>/g, "") + " </li>"; } else { message = "<li>All tags are properly matched.</li>"; } console.log(message);
关键修改点
- 提取标签名:使用
tagNameRegex从起始标签中提取纯标签名(忽略属性部分),比如从<a href=https://example.com>中提取a。 - 匹配闭合标签:通过标签名生成正确的闭合标签格式,或者直接用
closingTagRegex提取闭合标签的标签名进行比对,确保只匹配标签名一致的闭合标签。 - 优化循环逻辑:改用
while循环配合reset标记,更清晰地处理数组元素移除后的遍历问题。 - 增加空值判断:避免
foundArr为null时出现报错。
测试上述代码,输入正确的带属性锚点标签时,会输出All tags are properly matched.,不再产生误判。
内容的提问来源于stack exchange,提问作者flarow432
相关产品推荐
相关产品推荐

