我遇到以下问题:匹配文件名中所需的数据,如下所示:
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"找不到?
答案 0 :(得分:40)
让季节组可选是很容易的:
(^.*?)(?:\Ws(?:eason )?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art )?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)
使用非捕获组((?:...)
)加上0或1个量词(?
)。我确实必须让第一组非贪婪,以防止它与名称的season
部分匹配。
我还将eason
和art
个可选字符串设置为非捕获可选组而不是字符类。
结果:
>>> 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')