如何让Python正则表达式不那么贪婪
我正在尝试在Python中匹配电视节目文件名中的节目名称和季/集号,文件名格式如下:
Show.One.S01E05.720p.HDTV.x264-CTU.mkv
还有
Show.Two.S08E02.HDTV.XviD-LOL.avi
我使用的正则表达式是:
(?P<show>[\w\s.,_-]+)\.[Ss]?(?P<season>[\d]{1,2})[XxEe]?(?P<episode>[\d]{2})
这个表达式在“Show Two”上能正确匹配,给我返回了 Show Two
、08
和 02
。但是在“Show One”中,720的存在让我得到了 7
和 20
作为季和集号。
如果我去掉 [XxEe]
后面的 ?
,那么它就能匹配两种类型的文件名,但我希望这个范围是可选的,以便在文件名中没有集号标识符的情况下也能匹配。
我尝试使用 ??
来让 [XxEe]
的匹配不那么贪婪,正如Python文档中 re 模块部分所述,但这并没有效果。
我该如何捕捉到系列名称部分和季/集部分,同时忽略字符串的其余部分呢?
3 个回答
0
在正则表达式的末尾加一个点:
(?P<show>[\w\s.,_-]+)\.[Ss]?(?P<season>[\d]{1,2})[XxEe]?(?P<episode>[\d]{2})\.
here __^
1
试试这个:
v
(?P<show>[\w\s.,_-]+?)\.[Ss]?(?P<season>[\d]{1,2})[XxEe]?(?P<episode>[\d]{2})
3
改变第一个匹配的贪婪程度:
p=re.compile('(?P<show>[\w\s.,_-]+?)\.[Ss]?(?P<season>[\d]{1,2})[XxEe]?(?P<episode>[\d]{2})')
print p.findall("Game.of.Thrones.S01E05.720p.HDTV.x264-CTU.mkv")
[('Game.of.Thrones', '01', '05')]
print p.findall("Entourage.S08E02.HDTV.XviD-LOL.avi")
[('Entourage', '08', '02')]
注意第一个组中的+
后面有一个?
。
解释:
第一个匹配会“吃”掉太多内容,所以降低它的贪婪程度可以让后面的匹配更快找到。 (顺便说一下,这个例子其实不是很好,我本来会改一下名字,因为听起来有点像 Warezzz 的东西,老实说 ;-))