正则表达式 - 我只想匹配正则表达式中的开始标记

时间:2009-02-23 10:51:11

标签: c# .net html regex tags

我正在创建一个正则表达式,我只想匹配错误的标签,如:<p> *some text here, some other tags may be here as well but no ending 'p' tag* </p>

 <P>Affectionately Inscribed </P><P>TO </P><P>HENRY BULLAR, </P><P>(of the western circuit)<P>PREFACE</P>

在上面的相同文字中,我希望得到<P>(of the western circuit)<P>的结果,并且不应该捕获任何其他内容。我正在使用它,但它不起作用:

<P>[^\(</P>\)]*<P>

请帮忙。

5 个答案:

答案 0 :(得分:7)

正则表达式并不总是xml / html类型数据的好选择。特别是,属性,区分大小写,注释等都会产生很大的影响。

对于xhtml,我使用XmlDocument / XDocument和xpath查询。

对于“非x”html,我会查看HTML Agility Pack和相同的内容。

答案 1 :(得分:1)

匹配第一组:

(?:<p>(?:(?!<\/?p>).?)+)(<p>)

匹配第二个<p>

<P>(of the western circuit)<P>PREFACE</P>

注意:我通常会说:“不要用正则表达式做HTML,而是使用解析器”。但我不认为解决方案可以解决具体问题,解析器可能只是忽略/透明地处理无效标记。

答案 2 :(得分:1)

我知道在这种情况下发生这种情况不太可能(或者甚至是html合法的?),但是通用的未封闭的xml-tag解决方案将非常困难,因为您需要考虑嵌套标签会发生什么,例如

<p>OUTER BEFORE<p>INNER</p>OUTER AFTER</p>

我很确定到目前为止给出的正则表达式会匹配第二个<p>,即使它实际上并不是一个未闭合的<p>

答案 3 :(得分:0)

不是使用*进行最大匹配,而是使用*?进行最小化。

应该能够以

开头
<P>((?!</P>).)*?<P>

这使用负前瞻断言来确保在“<P>”匹配之间的每个点都不匹配结束标记。

编辑:更正了断言(感谢评论者)。

答案 4 :(得分:0)

到目前为止提供的所有解决方案都匹配第二个&lt; P&gt;,但这是错误的。如果有两个连续的&lt; P&gt;怎么办?没有关闭标签的元素?第二个匹配将不匹配,因为第一个匹配吃了它的开始标记。你可以像我在这里一样使用前瞻来避免这个问题:

@"<p\b(?>(?:[^<]+|<(?!/?p>))*)(?=<p\b|$)"

至于其余部分,我使用了“非初始或非其余”技术以及原子组来尽可能有效地引导正则表达式匹配(更重要的是,尽快失败)可能,如果它会去。)