正则表达式 - 如何识别一个模式直到找到第二个模式
我有一个文件,名字是特定的格式。比如说,它的名字是:
tv_show.s01e01.episode_name.avi
这是网络上电视节目集的标准命名方式。这个命名模式在网上几乎都是一样的,所以我想从这样命名的文件中提取一些信息。基本上,我想得到:
- 节目的标题;
- 季号
s01
; - 集号
e01
; - 文件扩展名。
我正在用Python 3脚本来实现这个功能。这个测试文件比较简单,因为我只需要这样做:
import re
def acquire_info(f="tv_show.s01e01.episode_name.avi"):
tvshow_title = title_p.match(f).group()
numbers = numbers_p.search(f).group()
season_number = numbers.split("e")[0].split("s")[1]
ep_number = numbers.split("e")[1]
return [tvshow_title, season_number, ep_number]
if __name__ == '__main__':
# re.I stands for the option "ignorecase"
title_p = re.compile("^[a-z]+", re.I)
numbers_p = re.compile("s\d{1,2}e\d{1,2}", re.I)
print(acquire_info())
然后输出结果是我预期的 ['tv_show', '01', '01']
。但是如果我的文件名是这样的呢? some.other.tv.show.s04e05.episode_name.avi
。
我该如何构建一个正则表达式,来获取所有在 "s\d{1,2}e\d{1,2}"
这个模式之前的文本呢?
顺便说一下,我没有在例子中放入获取扩展名的代码,我知道,但这不是我的问题,所以不重要。
3 个回答
0
我不是Python专家,但如果它可以进行命名捕获,像下面这样的一般写法可能会有效:
^(?<Title>.+)\.s(?<Season>\d{1,2})e(?<Episode>\d{1,2})\..*?(?<Extension>[^.]+)$
如果没有命名组,那就用普通的组。
一个问题可能会出现,如果标题中有一个 .s2e1.
的部分,这可能会遮盖真实的季和集信息。那就需要更多的逻辑来处理。上面的正则表达式假设标题、季、集和扩展名都存在,并且s/e是最右边的部分。
1
这里有一个方法,可以使用捕获组一次性提取你想要的所有信息:
>>> show_p = re.compile(r'(.*?)\.s(\d{1,2})e(\d{1,2})')
>>> show_p.match('some.other.tv.show.s04e05.episode_name.avi').groups()
('some.other.tv.show', '04', '05')
2
试试这个
show_p=re.compile("(.*)\.s(\d*)e(\d*)")
show_p.match(x).groups()
这里的 x 是你的字符串
编辑**(我忘了加上扩展名,这里是修正后的版本)
show_p=re.compile("^(.*)\.s(\d*)e(\d*).*?([^\.]*)$")
show_p.match(x).groups()
这是测试结果
>>> show_p=re.compile("(.*)\.s(\d*)e(\d*).*?([^\.]*)$")
>>> x="tv_show.s01e01.episode_name.avi"
>>> show_p.match(x).groups()
('tv_show', '01', '01', 'avi')
>>> x="tv_show.s2e1.episode_name.avi"
>>> show_p.match(x).groups()
('tv_show', '2', '1', 'avi')
>>> x='some.other.tv.show.s04e05.episode_name.avi'
>>> show_p.match(x).groups()
('some.other.tv.show', '04', '05', 'avi')
>>>