2013-03-18 36 views
7

我有以下问题从文件名相匹配所需要的数据是这样的:蟒正则表达式可选捕获组

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”块可以或可以不存在,或者可以写在短形式,如“第1条”或“海洋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”字符串。 如果找不到“season”,是否可以编写一个返回“None”作为group2的正则表达式?

回答

29

这是很容易足以使季节组可选的:使用非捕获组((?:...))加上0或1量词(?

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

。我确实必须使第一组非贪婪,以防止它匹配名称的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') 
+0

我是一个正则表达式左右新手,我是干什么错误试图使可选的‘季节’及编号,而不是分别比 – user2181741 2013-03-18 10:53:40