正则表达式在第一次比赛时停止


528

我的正则表达式模式看起来像

<xxxx location="file path/level1/level2" xxxx some="xxx">

我只对分配给位置的引号感兴趣。如果没有贪婪的开关,这岂不是像下面一样容易吗?

/.*location="(.*)".*/

似乎不起作用。


您的来源是什么,是HTML或xml还是什么?
Oskar Kjellin

20
为什么这是社区Wiki?这是一个真正的问题。现在为时已晚。
艾哈迈德·玛吉德

1
您用什么语言写?请不要对XML使用正则表达式。解析XML有很多更好的方法
Oskar Kjellin 2010年

3
如果您只想扫描简单的属性,则不会。正则表达式是适当且更快的。
codenheim 2010年

我要说的是,如果您以代码c#为例,那么最好使用linq。我怀疑,如果您有一个好的解析器,那么使用正则表达式会更好
Oskar Kjellin 2010年

Answers:


1092

您需要将正则表达式设为非贪婪,因为默认情况下,"(.*)"它将匹配所有"file path/level1/level2" xxx some="xxx"

相反,您可以使点星不贪心,从而使其与尽可能少的字符匹配:

/location="(.*?)"/

添加?一个量词(?*+)使它非贪婪。


32
FWIW,柜面你使用VIM,这个正则表达式需要有点不同:不是.*?它是.\{-}一个非贪婪匹配。
SooDesuNe 2011年

44
谢谢丹尼尔。“在量词(?,*或+)上加上?会使它变得非贪婪。” 对我有帮助的提示。
2014年

10
?描述了我在试图解决这个问题时的困惑。怎么合适
罗比·史密斯

1
我相信您可以说“懒惰”而不是“非贪婪”
Manticore

50

location="(.*)"除非您将其设为非贪婪location=some="xxx否则它将从“之后” 到“之后” 匹配。因此,您要么需要.*?(即使其变得非贪婪),要么更好地替换.*[^"]*


3
[^“] *也可能与大多数正则表达式引擎速度更快,因为它不需要目前的格局后,查找模式。
让·文森特

1
@Kip:您可能是对的,但.*?表示法比[^"]*
Bondax

如果我想使用[^“] *包含定界符怎么

如果您不知道^和[]的含义,则完全没有。大多数人都会明白。*
Vincent Gerris

31

怎么样

.*location="([^"]*)".*

这样可以避免使用。*进行无限搜索,并且将与第一个引号完全匹配。


由于grep差异,如果要考虑可移植性,则上述应该是首选模式。
乔什·哈布达斯

22

如果您的引擎支持,请使用非贪婪匹配。添加?内捕获。

/location="(.*?)"/


1

由于您使用的是量化子模式,并且如Perl Doc中所述

默认情况下,量化的子模式为“ 贪婪 ”,也就是说,它将尽可能多地匹配(给定特定的起始位置),同时仍允许其余模式匹配。如果希望它 与最小次数匹配,请在量词 后面加上 “?” 。请注意,含义不变,只是“贪婪”:

*?        //Match 0 or more times, not greedily (minimum matches)
+?        //Match 1 or more times, not greedily

因此,要使您的量化模式达到最小匹配,请遵循?

/location="(.*?)"/

1

这是另一种方式。

这是您想要的那个。这很懒[\s\S]*?

第一项: [\s\S]*?(?:location="[^"]*")[\s\S]*替换为:$1

说明https : //regex101.com/r/ZcqcUm/2


为了完整起见,这是最后一个。这很贪心[\s\S]*

最后一项:[\s\S]*(?:location="([^"]*)")[\s\S]* 替换为:$1

说明https : //regex101.com/r/LXSPDp/3


这两个正则表达式之间只有1个区别,那就是 ?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.