我需要一个与html中的CDATA元素匹配的正则表达式

时间:2014-02-10 15:57:21

标签: c# .net regex parsing cdata

我正在尝试编写一个正则表达式来匹配c#中的web爬虫类中的HTML中的CDATA元素。

我过去使用的是\<\!\[CDATA\[(?<text>[^\]]*)\]\]\>,但问题是如果CDATA标记中包含javascript,则会在array []元素存在时中断。否定是必要的,因为如果有多个我想要匹配它们。

如果我修改正则表达式以匹配结束'&gt;'我有同样的问题。任何带有&gt;的javascript运算符打破了我的正则表达式。

所以我需要在这个正则表达式中使用否定前瞻来忽略']]&gt;'。我怎么写这个?

以下是一些快速设置问题的测试数据:

        //Matches any
        string pattern = @"\<\!\[CDATA\[(?<text>[^\]]*)\]\]\>";
        var rx = new Regex(pattern, RegexOptions.Singleline);

        /* Testing...*/

         string eg = @"<![CDATA[TesteyMcTest//]]><![CDATA[TesteyMcTest2//]]><![CDATA[TesteyMcTest//]]><!             [CDATA[TesteyMcTest2//]]>
         <![CDATA[Thisisal3ongarbi4trarys6testwithnumbers//]]><![CDATA             [thisisalo4ngarbitrarytest6withumbers123456//]]><![CDATA[ this.exec = (function(){ var x =              this.GetFakeArray(); var y = x[0]; return y > 3;});//]]> ";

         var mz = rx.Matches(eg);

此示例匹配CDATA的每个实例,但最后一个实例除外,其中包含javascript和']','&gt;'

提前致谢,

2 个答案:

答案 0 :(得分:2)

问题是您的<text>子模式是错误的!您无需避免],您需要避免 ]后跟]> 。您可以改为使用此子模式:

(?<text>(?>[^]]+|](?!]>))*) 

整个模式:(请注意,许多角色不需要转义)

@"<!\s*\[CDATA\s*\[(?<text>(?>[^]]+|](?!]>))*)]]>"

我添加了两个\s*来匹配您的所有示例字符串,但如果您想禁止这些可选空格,则可以删除\s*

答案 1 :(得分:0)

以下是否适用于您:http://regex101.com/r/cT0pT0

\[CDATA\[(.*?)\]\]>

似乎以匹配您要求的内容...这里的关键是.*?(非贪婪匹配)的使用在您获得{{1 }}

注意 - 使用正则表达式解析HTML通常是一个非常糟糕的想法。有很多好的库可以更有效地完成这项工作。

参见例如What is the best way to parse html in C#?