如何从文件名中提取电影标题

6

我想从电影文件名中提取元数据(标题和年份)。

文件名的格式并不标准,但也不是随机的,因此我尽可能覆盖了许多情况。
为了给你一个想法,这是一些文件名的示例:

samples = ['The Movie Title.avi',
           'The Movie Title DVDRIP. Useless.info.avi',
           'The Movie Title [2005].avi',
           'The Movie Title (2005) [Useless.info].avi',
           'The Movie Title 2005 H264 DVDRip Useless-Info.avi',
           'The Movie Title 2005 XviD Useless info.avi',
           'The Movie Title {2005} DVDRIP. UselessInfo.avi',
           'The.Movie.Title.2005.Useless.info.avi',
           '[Useless.info]_The.Movie.Title.2005.Useless.avi']

无论在哪里出现UselessInfo,都是因为那里写的内容可能是任何东西,不能用来获取信息(从文件到文件的变化)。还要注意,'The Movie Title'可能是一个带有数字或非字母字符的东西,例如:The Movie Title 2 - The Return'

预期输出应该是一个像这样的字典:

metadata = {'title': 'The Movie Title', 'year': '2005'}

目前我正在使用一系列正则表达式,但我不知道是否有更好的方法来实现这个功能。


1
这是一个有趣的问题,但你的一些步骤可能会破坏你试图提取的标题。第5步将从任何以数字开头的电影标题中删除数字(例如“60秒”)。 - Maciek
我相信你应该有更大的垃圾关键词集,而不仅仅是 ['dvd', 'DVD'] :) 你可以尝试更灵活的扩展名剥离:name = name[:name.rfind('.')] - 还有那些旧的 *.mpeg 扩展名。 - Maciek
@Maciek:这不是真的:步骤5仅删除非字母数字字符 - Rik Poggi
@Rik 在评论中写道:“我看不出这怎么可能行得通:我将有一个巨大的电影列表要与另一个巨大的电影列表进行比较”。因此,也许可以分开或只是更新这个问题陈述,并提出问题,指出这个问题:“我必须移动列表。每个移动名称的格式可能不同。如何以聪明的方式比较这些列表(当前想法:一组正则表达式)。” - Grzegorz Wierzowiecki
@RikPoggi,我想知道你用于示例的正则表达式链是否可以分享一下? - Siddharth Gupta
3个回答

12

那是很久以前的事情了!但如果有人需要,我发现这个名为PTN的Python库非常有用!非常感谢编写它的人!

安装方法: pip install parse-torrent-name

import PTN

torrentName = "[Torrent9.info ] Silicon.Valley.S04E04.VOSTFR.WEB-DL.XviD-T9.avi"

info = PTN.parse(torrentName)

print(info)

输出:{'episode': 4, 'codec': 'XviD', 'title': 'Silicon.Valley.', 'group': 'T9', 'website': 'Torrent9.info', 'excess': 'VOSTFR', 'season': 4, 'quality': 'WEB-DL'}

看起来正是您所需的!


虽然这个链接可能回答了问题,但最好在此处包含答案的必要部分并提供链接作为参考。仅有链接的答案如果链接页面发生更改,则可能变得无效。 - slfan
1
我非常感激自己决定谷歌这个看似晦涩的问题。谢谢你分享这个宝藏,你救了我! - Anchith Acharya

2

为什么不下载一个数据库(例如维基百科)的电影名称和日期列表,然后将文件名与该列表进行比较?有很多边缘情况可能更有效。


我看不出这怎么可能行得通:我将有一个巨大的电影列表与另一个巨大的电影列表进行比较(我怀疑这需要一些时间),由于我不可能拥有所有电影的列表,因此仍然存在不确定性,这将导致未知结果而不是部分结果。只要用户能够覆盖一堆几乎正确的结果,对我来说,一个好的正则表达式算法似乎更好。 - Rik Poggi
好的,我觉得也许电影列表会很有限。无论如何,这里还有另一种可能性:为什么不使用某种机器学习算法呢? - charlax
@RikPoggi 用一些局部敏感哈希算法来进行比较怎么样? - ipavlic

2

正如您在评论中提到的,将“文件名处理”转换为“标准化的电影标题形式”的目的是为了比较两个列表。

使用您目前的方法可能会错过很多特殊情况。

首先,您需要仔细考虑接受哪些变化。您已经提到了“电影”和“the”的不同位置 - 那么拼写错误和大小写敏感呢? 单词的顺序呢?

与其让您的代码越来越长,我建议您寻找一种通用解决方案。

我的脑海中浮现出一些想法 - 您可以选择其中喜欢的部分,按照自己的意愿混合一下,稍加调整就能得到完美的效果:

  • LCS:最长公共子串问题最长公共子序列问题 - 适用于:
    • 单词的顺序很重要。
    • 通用性强,只需将子串/子序列设置为输入的百分比(最大值、最小值、平均值或两个文件名的总和-由您选择)
  • 匹配不是字符串,而是一组单词。由此,您可以抵抗单词顺序、重复等。由于您在Python中编写,因此很容易创建单词集合的集合或单词集合的映射。以下是一些提示:
    • 对于每部电影-而不是使用正则表达式整个字符串:(1)将电影文件名拆分为单词(2)消除:"the"、"movie"等(3)剪切最重要的部分("walking"-"ing"->"walk"等)。(4)将剩下的单词放入集合中(5)生成的集合是表示电影的集合。
    • 对于每个列表:将所有电影文件名转换为集合(如上所述),并将所有这些集合放入集合中(现在您有一组字符串的集合-是的)
    • 对于列表A和B:只需执行A ^ BA - B,再次-您需要什么(请查看Python手册:集合
  • 如果以后需要将表示电影的集合还原为电影文件名。在创建列表A、B时,您需要创建映射MA、MB,将“单词集合”映射为“文件名”。
  • 再次LCS,但现在想象一下您的字母表是单词。如果您不熟悉形式语言术语 - 想象一下您的电影名称是用特殊字母写成的,每个字母恰好是一个单词。由此,您就有了一系列单词,并且可以搜索单词子序列。现在应用LCS将为您提供电影标题中保留顺序的最长公共单词集

我的目的是从文件名中提取(猜测)信息,我没有存储列表来与我的结果进行比较,我只是使用那些信息与第三方软件一起检索更多信息。话说回来,你的建议很有趣,特别是第二个建议,我从未想过这样的方法!不过,我必须诚实地说,这些看起来需要做太多工作,所以我现在不会实施任何一个建议,但是知道我的选择还是很好的 :) - Rik Poggi
也许你将来会从这些技巧中受益 :) - Grzegorz Wierzowiecki
我只是想表明解决这类问题有很多方法,所以如果你计划将来开发这样的软件,也许你会找到实现它的资源 :)。 - Grzegorz Wierzowiecki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接