了解查找多行HTML注释的RegEx

时间:2014-01-13 21:00:50

标签: c# javascript html .net regex

我在这里找到了一个RegEx http://regexadvice.com/forums/thread/36397.aspx,我正在寻找一个我不理解的行为的解释。 RegEx应该可以找到不在脚本或样式标记内的多行HTML注释。我正在使用它来构建一个可以在构建后删除浏览器可访问注释的应用程序。例如,找到这个

<!-- I am an ordinary comment
and I need two lines -->

但不是这个

<script language="javascript1.2">
<!--
function window_Onload()
{   
    alert('I am the on load event');
}
window.onload=window_Onload;
//-->
</script>

一旦找到,我可以删除第一个评论块而忽略第二个。

以下模式可以完美地完成上述工作:

string multilinePattern = @"<!--((?!-->).)+-->(?>((?!</?(script|style)).)*)(?!</(script|style))";
match = Regex.Match(text, multilinePattern);
                    if (match.Success)
                    {
                        output.WriteLine("{0}", match.Value);
                    }

这段代码会给我一个文件,其中包含所有不在脚本或样式标记内的html注释,但它会做一些我无法获得的其他内容。

这是 示例1 的HTML和返回:

HTML:

<!-- Outside Table -->
<table summary="<%= GetLocalResourceObject("LayoutTable.SummaryText") %>" cellspacing="0" cellpadding="0" border="0" width="650" align="center">
    <tr>
        <td class="tableHeader">&nbsp;</td>

返回:

<!-- Outside Table -->

现在,这是 示例2 的HTML和返回:

HTML:

<!-- Outside Table -->

<table  summary="<%= GetLocalResourceObject("LayoutTable.SummaryText") %>" class="tabTableCell"   cellpadding="0" cellspacing="0" width="750" align="center" >

    <tr>

        <td class="tableHeader">&nbsp;</td>

返回:

<!-- Outside Table -->

<table  summary="<%= GetLocalResourceObject("LayoutTable.SummaryText") %>" class="tabTableCell"   cellpadding="0" cellspacing="0" width="750" align="center" >

    <tr>

示例2是错误的:我不想在匹配结果中包含那个html块。但是我在示例1和示例2中看到的唯一区别是示例2中“外表”符号后面的额外换行符。

所以我的问题是,正则表达式中是什么导致匹配将html一直包含在示例2中的TR标记中。我需要更改以使Regex与示例2匹配相同作为例1的方式?

2 个答案:

答案 0 :(得分:1)

好的,这是如何用HtmlAgilityPack

完成的
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);

var comments = doc.DocumentNode
                .Descendants()
                .Where(d => d.Name == "#comment")
                .Select(d => d.InnerText)
                .ToList();

答案 1 :(得分:0)

在我的测试中,它只匹配两种情况下的评论。但是如果我指定Singleline选项(你应该这样做),它在两种情况下都匹配整个shebang。可能是你在第二次测试中以Singleline模式进行了比赛,但不是第一次?

但无论如何,那是一个糟糕的正则表达式。在匹配注释之后,原子组匹配并使用任何不是SCRIPT或STYLE标记(打开或关闭)的内容,然后前瞻断言后面的内容不是关闭SCRIPT或STYLE标记。

评论结束后你不想消费任何东西;这应该都是一个负面的预测。例如:

(?inxs)
<!--((?!-->).)+-->
(?!
  ((?!</?(script|style)).)*
  </(script|style)
)

(?inxs)是内联模式修饰符;它会启用IgnoreCaseExplicitCaptureIgnorePatternWhitespaceSingleline模式。这里又是一行,作为C#逐字字符串:

@"(?ins)<!--((?!-->).)+-->(?!((?!</?(script|style)).)*</(script|style))"