【问题标题】:Regex - I only want to match the start tags in regex正则表达式 - 我只想匹配正则表达式中的开始标签
【发布时间】:2010-10-09 07:09:39
【问题描述】:

我正在制作一个正则表达式,我只想匹配错误的标签,例如:<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>

在上面相同的文本中,我想得到&lt;P&gt;(of the western circuit)&lt;P&gt; 的结果,并且不应该捕获任何其他内容。我正在使用它,但它不起作用:

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

请帮忙。

【问题讨论】:

  • 请注意,在 HTML 中没有明确关闭的段落标签是 not 错误/无效的。它对 XHTML 无效,但是您必须使用小写标记才能有效。

标签: c# .net html regex tags


【解决方案1】:

对于 xml/html 类型的数据,Regex 并不总是一个好的选择。特别是属性、区分大小写、cmets 等都有很大的影响。

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

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

【讨论】:

  • 敏捷包非常适合在 html 中进行任何类似 xpath 的搜索(即使格式不正确!)
【解决方案2】:

匹配组之一:

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

匹配第二个&lt;p&gt;

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

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

【讨论】:

    【解决方案3】:

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

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

    我很确定到目前为止给出的正则表达式将匹配那里的第二个&lt;p&gt;,即使它实际上不是未封闭的&lt;p&gt;

    【讨论】:

      【解决方案4】:

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

      应该可以开始

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

      这使用否定的前瞻断言来确保结束标记在“&lt;P&gt;”匹配之间的每个点都不匹配。

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

      【讨论】:

      • 这将匹配当然...需要零宽度前向断言...
      • 那仍然匹配 。您需要将点 放在 前瞻之后,而不是放在它之前。你这样做的方式,开始标记之后的第一个字符被点消耗,并且前瞻永远不会看到它。
      【解决方案5】:

      到目前为止提供的所有解决方案都与第二个

      匹配,但这是错误的。如果有两个连续的

      元素没有结束标签怎么办?第二个将不匹配,因为第一个匹配吃了它的开始标签。您可以像我在这里所做的那样使用前瞻来避免这个问题:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多