如何让Python正则表达式不那么贪婪

4 投票
3 回答
2167 浏览
提问于 2025-04-17 00:32

我正在尝试在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 Two0802。但是在“Show One”中,720的存在让我得到了 720 作为季和集号。

如果我去掉 [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 的东西,老实说 ;-))

撰写回答