我一直在研究一个正则表达式,从视频的文件名中获取电视节目或电影的名称、播出年份(如果有的话)、季号和集号。我有一个正则表达式(如下),它似乎适用于双年度日期的节目(其中一个年份在节目/电影名称中,另一个年份是它播出的年份),适用于电影和电视节目。对于电视节目,如果格式是SXXEXX或XXX,它可以获取季节和剧集编号。我一直在regex101.com测试引擎中测试它。如果文件名中不存在年份,表达式将不会返回任何内容。此外,如果文件名有一个4位数的数字,实际上是节目名称的一部分,它会认为这是播出年份(即"the 4400")。如何修改此表达式以处理我所描述的额外条件?
最终目标是,我想把它放进一个python脚本中,该脚本可以查询像TheTVDB.com这样的网站,如果文件是电影或电视节目,这样我就可以把我庞大的视频库排序到电视节目和电影文件夹中。
(?P<ShowName>.*)[ (_.]#Show Name
(?=19[0-9]d|20[0-4]d|2050) #If after the show name is a year
(?P<ShowYear>d{4,4}) # Get the show year
| # Else
(?=Sd{1,2}Ed{1,2})
S(?P<Season>d{1,2})E(?P<Episode>d{1,2}) #Get the season and Episode information
|
(d{1})E(d{1,2})
这是我使用的测试数据
- 射箭.2009.S04E13
- 太空1999 1975
- 空间:1999(1975)
- 空间.1999.1975.S01E01
- 太空1999。(1975)
- 400.204.mkv
- 太空1999(1975)v.2009.01E13.标题.avi
- 青少年.wolf.S4E12.HDTV.x264
- Se7en。(1995).avi
- 如何训练你的龙2
正则表达式无法正确处理以下测试数据:
- 400.204.mkv
- 青少年.wolf.S4E12.HDTV.x264
- 如何训练你的龙2
更新:这是基于注释的新表达式。它的工作效果要好得多,但在表达式下面列出的3个文件名方面遇到了困难。
(?P<ShowName>.*)#Show Name
(
[ (_.]
(
(?=d{4,4}) #If after the show name is a year
(?P<ShowYear>d{4}) # Get the show year
| # Else no year in the file name then just grab the name
(?P<otherShowName>.*) # Grab Show Name
(?=Sd{1,2}Ed{1,2}) # If the Season Episode patterns matches SX{1,2}EX{1,2}, Then
S(?P<Season>d{1,2})E(?P<Episode>d{1,2}) #Get the season and Episode information
| # Else
(?P<Alt_S_E>d{3,4}) # Get the season and Episode that looks like 211
)
|$)
- Se7en
- 公元前10000年(2010年)
- v.2009.01E13.标题.avi
- 射箭.2009.S04E13
我对您的正则表达式做了一些修改,如果我理解正确的话,它似乎可以工作。
^(
(?P<ShowNameA>.*[^ (_.]) # Show name
[ (_.]+
( # Year with possible Season and Episode
(?P<ShowYearA>d{4})
([ (_.]+S(?P<SeasonA>d{1,2})E(?P<EpisodeA>d{1,2}))?
| # Season and Episode only
(?<!d{4}[ (_.])
S(?P<SeasonB>d{1,2})E(?P<EpisodeB>d{1,2})
| # Alternate format for episode
(?P<EpisodeC>d{3})
)
|
# Show name with no other information
(?P<ShowNameB>.+)
)
查看regex101 上的演示
编辑:我已经更新了regex来处理您在评论中提到的最后三种情况。
一个主要的问题是在主替换中没有parens,所以它包含了整个regex。我还必须添加一个替换,以不允许名称后面的年份/剧集格式。
因为有太多不同的可能布局,它们可能相互冲突,所以regex最终是不同场景的大量交替。例如,为了匹配一个根本没有年份或剧集信息的标题,我必须在整个正则表达式周围添加一个替换项,如果找不到任何已知的模式,就匹配整个正则表达式。
注意:现在你似乎已经扩大了演出年份,以匹配任何四位数字,所以没有必要进行展望。换句话说,(?=d{4,4})(?P<ShowYear>d{4})
与(?P<ShowYear>d{4})
是相同的。这也意味着你的剧集格式必须只匹配3位数,而不是4位数。否则,就无法将一个独立的4位数序列区分为一年或一集。
一般模式:
[ (_.]+ the delimiter used throughout
(?P<ShowNameA>.*[^ (_.]) the show name, greedy but not including a delimiter
(?P<ShowNameB>.+) the show name when it's the whole line
格式A(可能有季节和插曲的年份):
(?P<ShowYearA>d{4})
([ (_.]+S(?P<SeasonA>d{1,2})E(?P<EpisodeA>d{1,2}))?
格式B(仅限季节和剧集):
(?<!d{4}[ (_.])
S(?P<SeasonB>d{1,2})E(?P<EpisodeB>d{1,2})
格式C(剧集的备用格式):
(?P<EpisodeC>d{3})
如果可以的话,我调整了brian的regex以匹配之类的东西
商店名称201X.SXXEXX.XSUB.VOSTFR.720p.HDTV.x264-ADDiCTiON.mkv-
这是(PHP PCRE)
/^(
(?P<ShowNameA>.*[^ (_.]) # Show name
[ (_.]+
( # Year with possible Season and Episode
(?P<ShowYearA>d{4})
([ (_.]+S(?P<SeasonA>d{1,2})E(?P<EpisodeA>d{1,2}))?
| # Season and Episode only
(?<!d{4}[ (_.])
S(?P<SeasonB>d{1,2})E(?P<EpisodeB>d{1,2})
)
|
# Show name with no other information
(?P<ShowNameB>.+)
)/mx