检查HTML字符串是否有未打开的标签

时间:2010-07-02 09:11:23

标签: c# .net html-parsing

我有一个字符串作为HTML源代码,我想检查字符串的HTML源代码是否包含未打开的标记。

例如,下面的字符串在WAVEFORM之后包含</u>,其中没有开放<u>

WAVEFORM</u> YES, <u>NEGATIVE AUSCULTATION OF EPIGASTRUM</u> YES,

我只想检查这些类型的未打开标签,然后我必须将open标签附加到字符串的开头?

2 个答案:

答案 0 :(得分:6)

对于这种特定情况,您可以使用HTML Agility Pack断言HTML是否格式正确,或者您是否打开了标签。

var htmlDoc = new HtmlDocument();

htmlDoc.LoadHtml(
    "WAVEFORM</u> YES, <u>NEGATIVE AUSCULTATION OF EPIGASTRUM</u> YES,");

foreach (var error in htmlDoc.ParseErrors)
{
    // Prints: TagNotOpened
    Console.WriteLine(error.Code);
    // Prints: Start tag <u> was not found
    Console.WriteLine(error.Reason); 
}

答案 1 :(得分:0)

不那么容易。你不能直接使用HTML解析器,因为它不是有效的HTML,但是由于正则表达式无法应对嵌套或其他HTML复杂问题,所以你不能轻易地将正则表达式抛出。

你可以做的最好的事情可能是使用正则表达式来查找每个标记结构,例如。类似的东西:

<(\w+)(?:\s+[-\w]+(?:\s*(?:=\s*(?:"[^"]*"|'[^']*'|[^'">\s][^>\s]*)))?)*\s*>
|</(\w+)\s*>
|<!--.*?-->

从一个空的标签到开放列表和一个空的标签到关闭列表开始。对于字符串中的每个匹配,请查看组1和组2以查看是否有开始或结束标记。 (或者你可以忽略的评论。)

如果你有一个开始标记,你需要知道它是否需要关闭,即。如果它是EMPTY内容模型标签之一,例如<img>。如果元素为EMPTY,则不需要关闭,因此您可以忽略它。 (如果你有XHTML,这就容易多了。)

如果您有一个开始标记,请将正则表达式组中的标记名称添加到标记到关闭列表中。如果你有一个结束标记,请从标记到结束列表的末尾取一个标记(它应该是与那里相同的标记名称,否则你的标记无效。如果没有标记标签到关闭列表,而是将标签名称添加到标签到打开列表。

一旦你到达输入字符串的末尾,以相反的顺序将每个标记到开放的标记添加到字符串中,并将标记附近的关闭标记附加到结尾,再次以相反的顺序。

(是的,我正在使用正则表达式解析HTML。我认为这样的肮脏表明了你不想要的原因。如果有什么可以避免已经在标签中间剪断你的标记,那么这一点。)