在Python中使用正则表达式从文件名中获取剧集编号

4
我多年来在媒体服务器上收集了大量的电视剧。我编写了一个脚本,使用适当的文件名方案对它们进行重命名,但在尝试针对多个文件命名方案时遇到了一些正则表达式问题。
以下是我的当前函数,适用于从采用“s01e01”格式的文件名中获取剧集编号。
def getEpisode(filename):
    matches = re.findall(r"e[0-9][0-9]", filename)
    if len(matches) == 1:
        episode = matches[0]
        episode = stripEp(episode)
        return episode  
    else:
        return False

def stripEp(target):
    target = target.strip()
    target = target.strip('abcdefghijklmnopqrstuvwxyz.')
    return target

我需要做的是在使用多个方案时从文件名中获取剧集号码。我花了一段时间搜索并尝试了以下方法。

matches = re.findall(r"(e[0-9][0-9]|E[0-9][0-9]|x[0-9][0-9]|X[0-9][0-9]|episode [0-9][0-9]|Episode [0-9][0-9]|\n[0-9][0-9])", filename)

这段代码可以在正则表达式测试工具(如RegexPal和Python Regex Tool)中使用。
然而,当我将其插入到我的函数中时,它却无法工作。这让我感到困惑,因为它似乎在上面链接的Python正则表达式工具中能够工作。任何帮助都将不胜感激。
编辑:以下是文件使用的一些方案示例。
Series Name s01e01.avi

Series Name 1x01.avi

Series Name episode 01.avi

01 Episode Title.avi

2
“Doesn't work” 的意思是它会失败并出现某种异常,或者根本找不到你需要的匹配项? - Bogdan
2
你有哪些方案呢?给我们一些例子来参考。 - RanRag
另外,尝试将预期输入通过getEpisode传递,而不是通过stripEp,并查看它是否返回预期的输出。然后,还要测试stripEp函数。这样,您就知道出了什么问题,需要调试的代码量也会变小。 - bigblind
刚刚在我的电脑上测试了正则表达式部分,没有问题。一定是其他原因。 - Bogdan
@Lattyware 很有趣,看起来他们使用了多种模式。 - Mike
显示剩余5条评论
2个回答

5
文件名中不包含'\n'。您可以使用^来表示字符串的开头,例如:
def getEpisode(filename):
    match = re.search(
        r'''(?ix)                 # Ignore case (i), and use verbose regex (x)
        (?:                       # non-grouping pattern
          e|x|episode|^           # e or x or episode or start of a line
          )                       # end non-grouping pattern 
        \s*                       # 0-or-more whitespaces
        (\d{2})                   # exactly 2 digits
        ''', filename)
    if match:
        return match.group(1)

tests = (
    'Series Name s01e01.avi',
    'Series Name 1x01.avi',
    'Series Name episode 01.avi',
    '01 Episode Title.avi'
    )
for filename in tests:
    print(getEpisode(filename))

产量
01
01
01
01

我删掉了else: return False,因为Python在函数末尾没有返回任何内容时会返回None。由于None的布尔值为False,所以你可以使用epsiode = getEpisode(filename); if episode: ...来测试是否匹配。


谢谢,看起来它在所有文件上都正常工作,但是那些以剧集编号开头的文件除外。使用 ^ 已经解决了这个问题。 - Mike

1

只是为了正则表达式的清晰度

re.findall(r"(?:e|x|episode|\n)(\d{2})", filename, re.I)

获取季节

re.findall(r"(?:s|season)(\d{2})(?:e|x|episode|\n)(\d{2})", filename, re.I)

谢谢你的帮助。看起来是“\n”没有起作用。 - Mike

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