2011-04-20 60 views
1

我正在尝试编写一个正则表达式,它会将完整路径文件名转换为给定文件类型的短文件名,减去文件扩展名。在Python中去贪婪正则表达式

例如,我试图用

re.search('/(.*?)\.bar$', '/def_params/param_1M56/param/foo.bar') 

根据Python的重新Docs软件以便得到从字符串的.bar文件只是名字,*?*的ungreedy版本,所以我期望得到

'foo' 

返回match.group(1)而是我

'def_params/param_1M56/param/foo' 

我在这里想念什么贪婪?

回答

8

你错过的并不是关于正则表达式引擎的贪婪:它们从左到右工作,所以/尽早匹配,然后.*?被迫从那里工作。在这种情况下,最好的正则表达式根本不涉及贪婪(你需要回溯工作;它会,但是如果有很多斜线可能需要很长时间才能运行),但是更明确的模式:

'/([^/]*)\.bar$' 
+0

到目前为止最好的答案。 – 2011-04-20 20:47:17

3

我会建议改变你的正则表达式,使它不依赖于贪婪。

您只需要扩展名之前的文件名.bar以及最后的/之后的所有文件。这应该这样做:

re.search(`/[^/]*\.bar$`, '/def_params/param_1M56/param/foo.bar') 

这样做是它匹配/,零个或多个字符(尽可能)是/然后.bar

+0

+1,先用最好的 – 2011-04-20 20:40:56

+0

的在你的正则表达式中'''是匹配任何东西,而不是扩展名文件的'.'。确保你用'\ .'逃避''。 – 2011-04-20 20:46:22

+0

Woops :)编辑。我希望这不是倒行逆施的原因,因为这与问题无关。 – orlp 2011-04-20 20:46:47

0

我并不了解非贪婪运营商那么好,但是对于特定问题的解决方案是使用([^ /] *?)

0

正则表达式从右侧开始。在开始时放一个*,它应该可以工作。

-1

试试这个关于大小:

匹配= re.search( '/def_params/param_1M56/param/foo.bar' '* /(*)栏$。?。' )

+0

如果你已经使用''。* /',我不认为你真的需要'。*?'。 '。*'也会起作用:)你能编辑你的问题吗,我可以再次提醒你吗? – 2011-04-20 20:55:15

0

我喜欢正则表达式,但这里不需要一个。

path = '/def_params/param_1M56/param/foo.bar' 
print path.rsplit('/',1)[1].rsplit('.')[0] 

path = '/def_params/param_1M56/param/fululu' 
print path.rsplit('/',1)[1].rsplit('.')[0] 

path = '/def_params/param_1M56/param/one.before.two.dat' 
print path.rsplit('/',1)[1].rsplit('.',1)[0] 

结果

foo 
fululu 
one.before.two 
+0

我发布这个问题后,我确实想到了一个。仍然想知道贪婪的本质,寿。你也可以使用'path.split('/')[ - 1] .split('。')[0]' – tel 2011-04-22 16:04:08

0

其他人已经回答了正则表达式的问题,但在这种情况下,比正则表达式更高效的方法:

file_name = path[path.rindex('/')+1 : path.rindex('.')]