所以我试图重命名文件以匹配plex mediaserver的命名约定。 (SxxEyy)
现在我有大量使用例如的文件。 411为S04E11。我编写了一个小函数,它将搜索此模式的出现并将其替换为正确的约定。像这样:
pattern1 = re.compile('[Ss]\\d+[Ee]\\d+')
pattern2 = re.compile('[\.\-]\d{3,4}')
def plexify_name(string):
#If the file matches the pattern we want, don't change it
if pattern1.search(string):
return string
elif pattern2.search(string):
piece_to_change = pattern2.search(string)
endpos = piece_to_change.end()
startpos = piece_to_change.start()
#Cut out the piece to change
cut = string[startpos+1:endpos-1]
if len(cut) == 4:
cut = 'S'+cut[0:2] + 'E' + cut[2:4]
if len(cut) == 3:
cut = 'S0'+cut[0:1] + 'E' + cut[1:3]
return string[0:startpos+1] + cut + string[endpos-1:]
这非常有效。但事实证明,一些文件名将在其中有一年,例如。 the.flash.2014.118.mp4在这种情况下,它将改变2014年。
我尝试使用
pattern2.findall(string)
这会返回一个像这样的字符串列表 - > [' .2014',' .118']但我想要的是一个匹配对象列表,所以我可以检查是否有2,在这种情况下使用第二个的开始/结束。我似乎无法在re文档中找到一些可以做到的事情。我错过了什么或者我需要采取完全不同的方法吗?
答案 0 :(得分:1)
您可以尝试将匹配锚定到文件扩展名:
pattern2 = re.compile(r'[.-]\d{3,4}(?=[.]mp4$)')
在这里,(?= ... )
是一个前瞻性断言,意味着必须存在正则表达式匹配的东西,但它不是匹配的一部分:
>>> pattern2.findall('test.118.mp4')
['.118']
>>> pattern2.findall('test.2014.118.mp4')
['.118']
>>> pattern2.findall('test.123.mp4.118.mp4')
['.118']
当然,您希望它能够与所有可能的扩展一起使用:
>>> p2 = re.compile(r'[.-]\d{3,4}(?=[.][^.]+$)')
>>> p2.findall('test.2014.118.avi')
['.118']
>>> p2.findall('test.2014.118.mov')
['.118']
如果剧集编号和扩展名之间有更多内容,匹配的正则表达式开始变得棘手,所以我建议使用非正则表达式处理它:
>>> f = 'test.123.castle.2014.118.x264.mp4'
>>> [p for p in f.split('.') if p.isdigit()][-1]
'118'
或者,您可以使用finditer
获取所有匹配项的匹配对象,并通过将迭代器转换为列表来扩展迭代器:
>>> p2 = re.compile(r'[.-]\d{3,4}')
>>> f = 'test.2014.712.x264.mp4'
>>> matches = list(p2.finditer(f))
>>> matches[-1].group(0)
'.712'