特定标记的正则表达式

问题描述:

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

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

谢谢。

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

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

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

你应该检查是否有“不贪心”的修改,让你的正则表达式将停在第一 occurence匹配的文本的</div>,而不是在最后之一。

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

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

取决于你的工作是什么语言 例如,在Perl中你的正则表达式修饰语使用:

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

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

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

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

取决于语言。如果蟒蛇,你缺少的re.S标志,像这样的(除去匹配):对于其他正则表达式实现存在

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

类似的标志,他们被称为“单行”或“多行”或类似的东西。

但是不要使用REGEXPS来描述HTML。这是维护地狱的直接途径。使用像美丽汤一样的HTML解析器。在这个方向检查theselinks有用的资源。

请,请相信,自己做一个巨大的青睐:使用HTML解析器来解析HTML。认真。这就是他们在那里。

HTML是一个非常复杂的语言。无论需要多长时间你会调整,摆弄,修复,珩磨你的正则表达式,总会有成为你失踪的案例。

无论如何,你必须告诉你的正则表达式引擎匹配多行而不是一行。在一些最流行的应用中,您可以通过应用/m修改器来实现。

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

+0

这可能会让我重新审视我的方法。我讨厌小猫! – 2008-09-17 01:45:07

问题是,元字符默认不匹配换行符。你必须使用单行修饰符来实现这一点。在.NET中,您可以使用RegexOptions。SINGLELINE作为最后一个参数的方法你使用,或直接在模式中使用的改性剂,e.g:

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

大多数语言有一些办法让。匹配换行符:

  • 在Java中:Pattern.compile(“pattern”,Pattern.MULTILINE);
  • 在Perl和Ruby:/模式/ M
  • 在VB:Regex.IsMatch(S, “模式”,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对于你的正则表达式总是安全的,那么不要让我阻止你(尽管如此,你应该三思而行,一个潜在的调试头痛)。

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

正则表达式并不是真正用于此目的的理想工具,但是如果您的情况足够简单以至于您不想真正解析HTML,则可以使用Microsoft专有的扩展来完成此操作在.NET中可用。有一个很好的解释,请参阅this nice article by Morten Maate

正则表达式本身并不足以解决您的问题。您需要更强大的功能,例如上下文无关文法。请参阅*的Chomsky hierarchy

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