1

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

例如,我试图从字符串中获取 .bar 文件的名称,使用

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

根据 Python re docs,*?是不贪婪的版本*,所以我期待得到

'foo'

返回match.group(1)但我得到了

'def_params/param_1M56/param/foo'

关于贪婪,我在这里错过了什么?

4

7 回答 7

8

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

'/([^/]*)\.bar$'
于 2011-04-20T20:41:32.333 回答
3

我建议更改您的正则表达式,使其不依赖于贪婪。

您只需要扩展名之前的文件名.bar和最终/. 这应该这样做:

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

它的作用是匹配/, then 零个或多个字符(尽可能多)而不是 /then .bar

于 2011-04-20T20:39:40.963 回答
0

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

file_name = path[path.rindex('/')+1 : path.rindex('.')]
于 2011-04-20T21:49:33.930 回答
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
于 2011-04-20T21:24:13.780 回答
0

我并没有声称完全理解非贪婪运算符,但解决该特定问题的方法是使用 ([^/]*?)

于 2011-04-20T20:40:05.163 回答
0

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

于 2011-04-20T20:40:11.440 回答
-1

试穿这个尺寸:

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

于 2011-04-20T20:42:17.983 回答