2014-01-13 54 views
0

我在这里找到RegEx http://regexadvice.com/forums/thread/36397.aspx,我正在寻找一个我不明白的行为的解释。 RegEx应该找到不在脚本或样式标签内的多行HTML注释。我正在使用它来构建一个可以在构建后去除浏览器可访问评论的应用程序。例如,发现这个了解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标签。我需要更改哪些内容才能使示例2与示例1中的示例1相同?这里

+0

这将为我返回正确的结果。另外:你真的不应该使用正则表达式来解析HTML。事实上,你问这个问题,并有问题匹配标记是你不应该这样做的确切原因。 –

+1

关于正则表达式和HTML有几十个问题,他们都说,不要做!改用HTMLAgilityPack。 – paqogomez

+1

@CasimiretHippolyte,有些方法可能会标记您可能认为不具有建设性的评论,而不是诉诸广告主题攻击。我试图有所帮助,我认为HTML敏捷软件包是去这里的方法。 – paqogomez

回答

0

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

但是,这是一个坏的正则表达式。在匹配注释之后,原子组匹配并消耗任何不是SCRIPT或STYLE标记(打开或关闭)的标记,然后预测声明以下内容不是关闭的SCRIPT或STYLE标记。

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

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

(?inxs)是内联模式修饰符;它打开IgnoreCaseExplicitCapture,IgnorePatternWhitespaceSingleline模式。这里再一次,所有在一行中作为C#逐字字符串:

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

虽然我可能会尝试HTML敏捷包(我只是没有足够的时间来学习这个项目的正则表达式),但这个表达完美无缺。我赞赏解释为什么它的工作,其他没有。 – mckreck

+0

另外,忘了提及,我没有在第二次测试中使用'SingleLine'模式,而不是第一次。这两种测试都是通过一次运行一个应用程序来实现的,这个应用程序可以迭代所有文件中的所有文本,并向其发回的匹配报告。所以如果一个测试使用'SingleLine'模式,另一个测试也是如此。 再次感谢。 – mckreck

1

OK是它如何与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();