Skip to main content
 首页 » 编程设计

python之在python中查找正则表达式的第二个匹配项的索引

2024年10月25日30开发

所以我正在尝试重命名文件以匹配 plex mediaserver 的命名约定。 ( SxxEyy )

现在我有大量使用 eg 的文件。 S04E11 为 411。我写了一个小函数来搜索这种模式的出现并将其替换为正确的约定。像这样:

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 个,在这种情况下使用 start/第二个结束。我似乎无法在重新文档中找到执行此操作的方法。我遗漏了什么,还是我需要采取完全不同的方法?

请您参考如下方法:

您可以尝试将匹配锚定到文件扩展名:

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'