我喜欢使用 HTML 解析器的建议,但让我提出一种枚举顶级文本(无封闭标签)区域的方法,您可以在闲暇时对其进行转换和重组。
本质上,您可以将每个顶级打开标记视为 {,并仅跟踪该标记的嵌套。与您想自己进行的常规解析相比,这可能足够简单。
以下是一些潜在的陷阱:
如果不是 XHTML,则需要一个始终为空的标签列表:
<hr> , <br> and <img> (are there more?).
对于所有开始标签,如果以 /> 结尾,则立即关闭 - {} 而不是 {。
不区分大小写 - 我相信您会想不区分地匹配标签名称(只需 lc 全部)。
超级宽松的浏览器解释,如
"<p> <p>" = "<p> </p><p>" = {}{
带引号的实体不允许包含 (它们需要使用 <),但也许浏览器在那里也是超级宽容的。
本质上,如果你想解析正确 HTML标记,没有问题。
所以,算法:
“前一个标签的结尾”=字符串的开始
反复搜索下一个开放标签(不区分大小写)或字符串结尾:
< *([^ >/]+)[^/>]*(/?) *>|$
句柄(前一个标签的结束,匹配的开始)作为所有标签之外的区域。
设置标记名=lc($1)。如果有 / ($2 不为空),则更新 end 并从 start 继续。否则,深度=1,
-
当 depth > 0 时,扫描下一个(也不区分大小写):
如果 $1,那么它是一个关闭标签 (depth-=1)。否则,如果不是 2 美元,那就是另一个开放标签;深度+=1。在任何情况下,继续循环(回到 1。)
回到开始(你又回到了顶级)。请注意,我在顶部说“扫描顶级打开标记的下一个开始,或字符串的结尾”,即确保处理挂在最后一个结束标记上的顶级文本。
就是这样。本质上,您可以忽略除当前正在监控的最顶层标签之外的所有其他标签,假设输入标记已正确嵌套(它仍然可以正常工作以防止 一些 类型的错误嵌套) .
另外,无论我在上面写了什么空格,都应该是任何空格(在 / 和标签名称之间,你可以使用任何你喜欢的空格)。
正如您所看到的,仅仅因为问题比完整的 HTML 解析稍微容易一些,并不一定意味着您不应该使用真正的 HTML 解析器 :) 您可能会搞砸很多事情。