【问题标题】:Matching TV and Movie File names with Regex使用正则表达式匹配电视和电影文件名
【发布时间】:2014-09-12 11:57:00
【问题描述】:

我一直在努力获取一个正则表达式来从视频的文件名中获取电视节目或电影名称、播出年份(如果存在)、季节#和剧集#。对于电影和电视节目,我有一个正则表达式(如下)似乎适用于具有双年日期的节目(其中一个年份在节目/电影名称中,另一个是它播出的年份)。对于电视节目,如果格式为 SXEXXX 或 XXX,它可以获取季节和剧集编号。我一直在regex101.com 测试引擎中对其进行测试。我苦苦挣扎的地方是,如果文件名中不存在年份,则表达式将不会返回任何内容。此外,如果文件名有一个 4 位数字,它实际上是节目名称的一部分,它认为这是播出的年份日期(即“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
          (?=S\d{1,2}E\d{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})

这是我正在使用的测试数据

  • archer.2009.S04E13
  • 空间 1999 1975
  • 空间:1999 (1975)
  • Space.1999.1975.S01E01
  • 空间 1999.(1975)
  • .4400.204.mkv
  • 空间 1999 (1975) v.2009.S01E13.the.title.avi
  • Teen.wolf.S04E12.HDTV.x264
  • Se7en.(1995).avi
  • 如何训练你的龙 2

正则表达式不适用于以下测试数据:

  • .4400.204.mkv
  • Teen.wolf.S04E12.HDTV.x264
  • 如何训练你的龙 2

更新:这是基于 cmets 的新表达式。它的效果要好得多,但在表达式下方列出的 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
          (?=S\d{1,2}E\d{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
  • 10,000BC (2010)
  • v.2009.S01E13.the.title.avi
  • archer.2009.S04E13

【问题讨论】:

  • 很难说出所有这些变化是什么,尤其是现在添加的示例。 v.2009.S01E13.the.title.aviarcher.2009.S04E13 的节目/年份/剧集部分是什么?
  • 它应该与space 1999 (1975) v.2009.S01E13.the.title.avi 做什么?节目名称是什么? 2009 年是一年吗?
  • 如果输入的文件名是v.2009.S01E13.the.title.avi。我的预期输出是 ShowName = v,Year = 2009,Season = 01,Episode = 13。空间 1999(1975)也是如此。 ShowName = 空间 1999,年份 = 1975
  • 好的,这说明了一件事,但space 1999 (1975) v.2009.S01E13.the.title.avi 是您列表中的一项。那应该是两个独立的项目吗?那会更有意义。
  • 我已更新列表以使这些文件名成为单独的项目

标签: regex regex-lookarounds


【解决方案1】:

我对你的正则表达式做了一些修改,如果我理解正确的话,它似乎可以工作。

^(
  (?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上查看演示

编辑:我已经更新了正则表达式来处理你在 cmets 中提到的最后 3 种情况。

一个主要问题是您没有围绕主要交替的括号,因此它包含了整个正则表达式。我还必须添加一个替代项,以允许名称后面没有任何年份/剧集格式。

因为您有很多可能相互冲突的不同布局,所以正则表达式最终变成了不同场景的大量交替。例如,要匹配一个根本没有年份或剧集信息的标题,我必须在整个正则表达式周围添加一个替换,如果它找不到任何已知模式,则匹配整个内容。

注意:现在您似乎已扩展放映年份以匹配任何四位数,因此无需前瞻。换句话说,(?=\d{4,4})(?P&lt;ShowYear&gt;\d{4})(?P&lt;ShowYear&gt;\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})

【讨论】:

  • 谢谢。我采用了您所做的并将其应用于更新的表达式。它似乎工作得更好,但仍在为 3 个文件名而苦苦挣扎。你能在原帖中查看我更新的部分吗?
  • @Talguy:我刚刚更新了我的答案,它符合你需要的一切。这是我的最终答案;我需要继续前进。希望它是可接受的!
  • 感谢所有帮助,这确实满足了我的需求。这是我对正则表达式的第一次冒险。这是令人困惑的东西,但是由于您的撰写,我看到了您的所作所为并理解了它。希望我可以将它应用到我的下一次正则表达式冒险中。
【解决方案2】:

如果可以的话,我调整了 brian 的正则表达式来匹配类似的东西

SHOW.NAME.201X.SXXEXX.XSUB.VOSTFR.720p.HDTV.x264-ADDiCTON.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

【讨论】:

  • 抱歉错过了这个建议。它有点工作,但不完全。我最终采用了 Brian 创建的内容并添加了标志来检测 720p 和 480p 关键字,以避免将它们检测为 EpisodeC 名称组。下面的正则表达式适用于我的测试集和您在上面提供的测试字符串。 ^( (?P.*[^ (.]) [ (.]+ ( (?P\d{4}) ([ (.]+ S(?P\d{1,2})E(?P\d{1,2}))? | (?.] ) S(?P\d{1,2})E(?P\d{1,2}) | (?P\d{3}[^720p|480p]) ) | (?P.+) )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多