python正则表达式可选捕获组

时间:2013-03-18 10:36:42

标签: python regex

我遇到以下问题:匹配文件名中所需的数据,如下所示:

miniseries.season 1.part 5.720p.avi
miniseries.part 5.720p.avi
miniseries.part VII.720p.avi     # episode or season expressed in Roman numerals

"第XX季"大块可能存在也可能不存在,或者可能以简短的形式书写,例如" s"或"海洋1"

在任何情况下,我都希望有4个捕获组作为输出:

group1 : miniseries
group2 : 1 (or None)
group3 : 5
group4 : 720p.avi

所以我写了这样的正则表达式:

(^.*)\Ws[eason ]*(\d{1,2}|[ivxlcdm]{1,5})\Wp[art ]*(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)

这只适用于我有一个完全指定的文件名,包括可选的"第XX季"串。 是否有可能编写一个返回"无"的正则表达式。作为group2,如果" season"找不到?

1 个答案:

答案 0 :(得分:40)

让季节组可选是很容易的:

(^.*?)(?:\Ws(?:eason )?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art )?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)

使用非捕获组((?:...))加上0或1个量词(?)。我确实必须让第一组非贪婪,以防止它与名称的season部分匹配。

我还将easonart个可选字符串设置为非捕获可选组而不是字符类。

结果:

>>> import re
>>> p=re.compile(r'(^.*?)(?:\Ws(?:eason )?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art )?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)', re.I)
>>> p.search('miniseries.season 1.part 5.720p.avi').groups()
('miniseries', '1', '5', '720p.avi')
>>> p.search('miniseries.part 5.720p.avi').groups()
('miniseries', None, '5', '720p.avi')
>>> p.search('miniseries.part VII.720p.avi').groups()
('miniseries', None, 'VII', '720p.avi')