2

我正在.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>

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

谢谢。

4

11 回答 11

6

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

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

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

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

于 2008-09-17T01:43:00.063 回答
1

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

m{<div id="super_special">.*?</span>}s
于 2008-09-17T01:37:19.983 回答
1

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

于 2008-09-17T01:37:45.317 回答
1

取决于语言。如果在 python 上,您缺少 re.S 标志,如下所示(删除匹配项):

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

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

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

于 2008-09-17T01:38:42.817 回答
1

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

(?s)(<div id="super_special">.*?</div>)
于 2008-09-17T01:43:25.490 回答
1

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

  • 在 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 对您的正则表达式始终是安全的,那么请不要让我阻止您(尽管即使那样,您也应该三思而后行,避免潜在的调试头痛)。

于 2008-09-17T01:48:09.923 回答
1

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

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

<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>

您应该检查“非贪婪”修饰符,以便您的正则表达式在第一次出现时停止匹配文本</div>,而不是在最后一次出现。

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

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

于 2008-09-17T01:50:27.203 回答
0

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

于 2008-09-17T01:38:33.940 回答
0

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

于 2008-09-17T01:38:35.597 回答
0

这些正则表达式建议都不起作用。根据它们是否贪婪,它们将匹配文档中的最后一个 </div>,或者匹配起始字符串之后的第一个 </div>,这可能是嵌套在你所在字符串中的 div有兴趣。

正则表达式并不是真正用于此目的的理想工具,但如果您的情况足够简单以至于您不想解析 HTML,您可以使用 Microsoft 专有的 .NET 中可用的正则表达式扩展来完成此操作。有关详细说明,请参阅Morten Maate 的这篇精彩文章

于 2008-09-17T02:41:23.557 回答
0

单独的正则表达式根本不足以解决您的问题。你需要更强大的东西,比如上下文无关的语法。请参阅Wikipedia 上的乔姆斯基层次结构。

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

于 2008-09-21T10:51:49.497 回答