用于查找未关闭的HTML标记的JavaScript库/函数
我目前正在寻找一种解决方案,从原始HTML的任意片段中查找并列出任何未关闭的HTML标记。我不觉得这应该是一个可怕的问题,但我似乎无法在JS中找到这样做的东西。不幸的是,这需要客户端,因为它用于将注释呈现到HTML页面。显然,注释有点麻烦,因为它们选择或应用的格式可能只适用于HTML元素的一部分(即,覆盖在现有HTML标记上的标记) 一个简单的用例是,您可能只希望呈现HTML页面的一部分,但稍后再注入其余部分。例如,想象一个假设的片段:用于查找未关闭的HTML标记的JavaScript库/函数,javascript,html,tags,Javascript,Html,Tags,我目前正在寻找一种解决方案,从原始HTML的任意片段中查找并列出任何未关闭的HTML标记。我不觉得这应该是一个可怕的问题,但我似乎无法在JS中找到这样做的东西。不幸的是,这需要客户端,因为它用于将注释呈现到HTML页面。显然,注释有点麻烦,因为它们选择或应用的格式可能只适用于HTML元素的一部分(即,覆盖在现有HTML标记上的标记) 一个简单的用例是,您可能只希望呈现HTML页面的一部分,但稍后再注入其余部分。例如,想象一个假设的片段: <p>This is my text <
<p>This is my text <StartDelayedInject/> with a comment I added. </p>
<p> But it doesn't exist until now. </p> <StopDelayedInject/>
这是我添加了注释的文本
但它直到现在才存在
我将做一些预处理来重建HTML,以便将部分元素包装到应用适当格式的span类型元素中。最初,这将以以下形式进行分析:
<p><span>This is my text</span></p>
这是我的文本
在一些用户操作之后,它将被修改为一个表单,例如:
<p><span>This is my text</span><span>with a comment I added.</span></p>
<p>But it doesn't exist until now.</p>
这是我添加了注释的文本
但它直到现在才存在
这是一个非常简单的例子(很明显,像ul元素和表这样的东西会变得更复杂),但给出了一般原则。然而,为了有效地做到这一点,我需要能够检查一段HTML,并找出有哪些标记已经打开(但没有关闭)。如果我知道这些信息,我可以将最后一个未终止的文本数据包装到一个范围中,关闭未关闭的标记,并知道在需要时返回到该点以注入剩余的内容。但是,我需要知道仍然打开的标签,这样当我注入或修改另一段内容时,我可以确保将其放在正确的位置(例如,在第一段中获得“添加了注释”)
根据我对上下文无关语法的理解,这应该是一项相对简单的任务。每次打开/输入或关闭/退出标记时,您可以保持一堆标记处于打开状态,但尚未关闭。话虽如此,我还是更愿意使用一个更成熟的解决方案库,而不是为此制作一个朴素的解析器。我假设有一些JSHTML解析器可以做到这一点,对吗?很多人都知道如何关闭标记,因此在某些时候他们计算得非常清楚。问题是JavaScript只能通过两种方式访问html:
如果您喜欢解析器的想法,John Resig创建了您可能想要引用的解析器。不完美,但下面是我检查打开/关闭标记之间不匹配的快速方法:
function find_unclosed_tags(str) {
str = str.toLowerCase();
var tags = ["a", "span", "div", "ul", "li", "h1", "h2", "h3", "h4", "h5", "h6", "p", "table", "tr", "td", "b", "i", "u"];
var mismatches = [];
tags.forEach(function(tag) {
var pattern_open = '<'+tag+'( |>)';
var pattern_close = '</'+tag+'>';
var diff_count = (str.match(new RegExp(pattern_open,'g')) || []).length - (str.match(new RegExp(pattern_close,'g')) || []).length;
if(diff_count != 0) {
mismatches.push("Open/close mismatch for tag " + tag + ".");
}
});
return mismatches;
}
函数查找未关闭的标签(str){
str=str.toLowerCase();
var标签=[“a”、“span”、“div”、“ul”、“li”、“h1”、“h2”、“h3”、“h4”、“h5”、“h6”、“p”、“table”、“tr”、“td”、“b”、“i”、“u”];
var不匹配=[];
tags.forEach(函数(tag){
变量模式_open=');
var模式_close='';
var diff_count=(str.match(新RegExp(pattern_open,'g'))| |[]).length-(str.match(新RegExp(pattern_close,'g'))| |[])length;
如果(差异计数!=0){
不匹配。推送(“标记“+标记+”的打开/关闭不匹配”);
}
});
返回不匹配;
}
我应该澄清一下,我有能力获取原始字符串(如果您有一个shell页面加载真实内容,这相当简单),因此我希望在允许浏览器将其添加到DOM之前使用HTML类型解析器。因此,浏览器无法“解析损坏的HTML”(除非我自己的代码无法正确附加终止符,或者如果原始HTML一开始就不好)。我也非常清楚正则表达式是一个糟糕的解决方案,因此我问了这个问题,并特别询问了“JS HTML解析器”。像Tidy/jTidy这样的库检测未终止的标记。问题是:是否存在一个JS库可以检测未终止的标记并报告丢失的标记?除非最近有一些我不知道的魔法,否则我不相信你可以用JavaScript对呈现的页面做你想做的事。我的意思是,理论上,您可以在页面加载时对整个HTML字符串运行HTML解析器。问题是,在这种情况发生之前,您的html已经加载,很可能在JS访问它之前显示渲染错误。这基本上是一个相当笨拙的解决方案。我还不知道有任何为JavaScript预先创建的客户端html解析器。是的,这也是我今天在搜索中找到的最好的一个。在此基础上构建可能是目前最好的选择。我还应该强调,让解析器添加结束标记是不够的,我还需要知道需要添加哪些结束标记,以跟踪下一个内容应该插入的位置。可能还值得注意的是,我已经用bison/yacc和lex之类的东西构建了解析器。我只是认为,在已经存在这么多HTML解析器的情况下,为这个目的构建和测试另一个HTML解析器是荒谬的。