在Regex中,为什么“((。| \ s)*?)”与“\ s *。*”不同

时间:2011-06-06 20:04:33

标签: regex

不是一个完整的新手,但我仍然不了解正则表达式的一切。我试图使用正则表达式删除< p>标签和我的第一次尝试

<p\s*.*>

如此贪婪,它抓住了整条线

<p someAttributes='example'>SomeText</p>

我让它与

一起工作
((.|\s)*?)

这似乎应该同样贪婪,任何人都可以帮助我理解为什么它不是吗?

尝试尽可能使这个问题成为非特定语言的问题,但如果它产生很大的不同,我会使用ColdFusion的reReplaceNoCase进行此操作。

3 个答案:

答案 0 :(得分:12)

关键区别在于*?部分,它创建了一个不情愿的量词,因此它尝试尽可能少地匹配。标准量词*贪心量词,并尝试尽可能匹配。

参见例如Greedy vs. Reluctant vs. Possessive Quantifiers

正如Seth Robertson所说,你可能想要使用一个不依赖于贪婪/不情愿行为的正则表达式。实际上,您可以编写占有性正则表达式以获得最佳性能:

<p\s*+[^>]*+>

此处,\s*+匹配任意数量的空格,而[^>]*+匹配除>之外的任意数量的字符。两个量词都不会在不匹配的情况下追溯,在不匹配的情况下可以改善运行时,并且在匹配的情况下也可以用于某些正则表达式实现(因为可以省略内部回溯数据)。

请注意,如果有其他标签以<p开头(长时间没有直接写HTML),那么您也会匹配这些标签。如果您不想这样,请使用这样的正则表达式:

<p(\s++[^>]*+)?>

这使得<p>之间的整个部分可选。

答案 1 :(得分:2)

好吧,正则表达式绝对匹配任何东西,所以这个问题没有实际意义。使用非贪婪的解析器可能会更接近你想要的但仍然会产生意想不到的结果。

虽然您不应该将html / xml与RE匹配,但您可能需要以下内容:

<p\s*([^>]*)>

将p的任何属性放入$ 1。

答案 2 :(得分:0)

<p\s*.*>

正在寻找'p',0个或更多个空格,0个或更多个字符,'&gt;' 。 “任何字符”组都包含“&gt;”,因此正则表达式会找到整行。