【问题标题】:Regex for Specific Tag特定标签的正则表达式
【发布时间】:2008-09-17 01:35:40
【问题描述】:

我正在 .NET 项目中处理正则表达式以获取特定标签。我想匹配整个 DIV 标签及其内容:

<html>
   <head><title>Test</title></head>
   <body>
     <p>The first paragraph.</p>
     <div id='super_special'>
        <p>The Store paragraph</p>
     </div>
     </body>
  </head>

代码:

    Regex re = new Regex("(<div id='super_special'>.*?</div>)", RegexOptions.Multiline);


    if (re.IsMatch(test))
        Console.WriteLine("it matches");
    else
        Console.WriteLine("no match");

我想匹配这个:

<div id="super_special">
   <p>Anything could go in here...doesn't matter.  Let's get it all</p>
</div>

我认为. 应该获取所有字符,但回车似乎有问题。我的正则表达式缺少什么?

谢谢。

【问题讨论】:

    标签: .net regex


    【解决方案1】:

    拜托,非常拜托,帮自己一个巨大的忙:使用 HTML 解析器来解析 HTML。严重地。这就是他们的目的。

    HTML 是一种非常复杂的语言。无论多长时间您将调整、摆弄、修复、磨练您的正则表达式,总会有一个您遗漏的案例。

    无论如何,您必须告诉您的正则表达式引擎匹配多行而不是仅匹配一行。在一些最受欢迎的应用程序中,您可以通过应用 /m 修饰符来做到这一点。

    但让我再说一遍:使用 HTML 解析器。每当有人使用正则表达式解析 HTML 时,一只小猫就会死去……

    【讨论】:

    • 这可能会让我重新审视我的方法。我讨厌小猫!
    【解决方案2】:

    开箱即用,没有特殊修饰符,大多数正则表达式实现不会超出行尾来匹配文本。您可能应该查看用于此类修饰符的正则表达式引擎的文档。

    我还有一个建议:提防贪婪!传统上,正则表达式 贪婪的,这意味着您的正则表达式可能会匹配这个:

    <div id="super_special">
      I'm the wanted div!
    </div>
    <div id="not_special">
      I'm not wanted, but I've been caught too :(
    </div>
    

    您应该检查“not-greedy”修饰符,以便您的正则表达式在&lt;/div&gt;第一次出现时停止匹配文本,而不是在最后一个。

    另外,正如其他人所说,考虑使用 HTML 解析器而不是正则表达式。它会为您省去很多麻烦。

    编辑:如果 &lt;div&gt;s 是嵌套的,即使是非贪婪的正则表达式也不会按预期工作!考虑使用 HTML 解析器的另一个原因。

    【讨论】:

      【解决方案3】:

      取决于您使用的语言。 例如,在 perl 中,您将使用正则表达式修饰符 s:

      m{<div id="super_special">.*?</span>}s
      

      【讨论】:

        【解决方案4】:

        您使用什么语言?在 .NET 中,您必须设置一个选项以确保它不是单行。

        【讨论】:

          【解决方案5】:

          问题是 .默认情况下,元字符不匹配换行符。您必须使用单行修饰符来实现这一点。在 .NET 中,您可以使用 RegexOptions.SingleLine 作为您正在使用的方法的最后一个参数,或者直接在模式中使用修饰符,例如:

          (?s)(<div id="super_special">.*?</div>)
          

          【讨论】:

            【解决方案6】:

            取决于语言。如果在 python 上,你缺少 re.S 标志,像这样(删除匹配):

            re.compile('<div id="super_special">.*?</div>',re.S).sub(your_html,'')
            

            其他正则表达式实现也存在类似的标志,它们被称为“单行”或“多行”或类似的名称。

            请勿使用正则表达式解析 HTML。这是通往维修地狱的直接途径。使用 HTML 解析器,例如 Beautiful Soup。检查 these links 以获取该方向的有用资源。

            【讨论】:

              【解决方案7】:

              大多数语言都有一些方法来制作 .匹配换行符:

              • 在 Java 中:Pattern.compile("pattern", Pattern.MULTILINE);
              • 在 Perl 和 Ruby 中:/pattern/m
              • 在 VB 中:Regex.IsMatch(s, "pattern", RegexOptions.Multiline)

              一般来说使用正则表达式来匹配XML/HTML并不是一个好主意,因为XML/HTML标签可以嵌套,例如:

                <div id="super_special">
                   <div>Nothing</div>
                   <p>Anything could go in here...doesn't matter.  Let's get it all</p>
                </div>
              

              ...在这里您可以轻松匹配:

                <div id="super_special">
                   <div>Nothing</div>
              

              另一方面,如果你知道确定你匹配的 HTML 对你的正则表达式总是安全的,那么不要让我阻止你(尽管,即使那样你也应该认为两次关于将您未来的自己从潜在的调试问题中拯救出来)。

              【讨论】:

                【解决方案8】:

                。 (点)匹配除换行符 \r 和 \n 之外的任何单个字符。大多数正则表达式风格也可以选择制作点匹配换行符。 .匹配 x 或(几乎)任何其他字符

                【讨论】:

                  【解决方案9】:

                  也许:.[\r\n].[\r\n]

                  【讨论】:

                    【解决方案10】:

                    这些正则表达式建议都不起作用。根据它们是否贪婪,它们将匹配文档中的最后一个

                    ,或者匹配起始字符串之后的第一个
                    ,这可能是嵌套在你所在字符串中的 div有兴趣。

                    正则表达式并不是真正用于此目的的理想工具,但如果您的情况很简单以至于您不想解析 HTML,您可以使用 Microsoft 专有的 .NET 中可用的正则表达式扩展来执行此操作.有关详细说明,请参阅 this nice article by Morten Maate

                    【解决方案11】:

                    单独的正则表达式根本不足以解决您的问题。你需要更强大的东西,比如上下文无关的语法。请参阅维基百科上的Chomsky hierarchy

                    换句话说(如前所述),不要使用正则表达式来解析 HTML。

                    【讨论】:

                      猜你喜欢
                      • 2023-03-24
                      • 2012-04-23
                      • 1970-01-01
                      • 2015-07-26
                      • 1970-01-01
                      • 2012-05-28
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多