2015-05-19 27 views
2

所以我想重命名文件以匹配plex mediaserver的命名約定。 (SxxEyy)查找python中正則表達式的第二個匹配的索引

現在我有很多文件使用例如。 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) 

這確實返回這樣的字符串列表 - > [「0.2014' ,」。 118'],但我想要的是匹配對象的列表,所以我可以檢查是否有2,並在這種情況下使用第二個的開始/結束。在重新編寫文檔時,我似乎無法找到這樣做的地方。我錯過了一些東西,還是需要採取完全不同的方法?

+0

沒有您的代碼有問題。如果我嘗試'the.flash.118.mp4',那麼在那裏找不到'118'。 –

+0

嗯,我剛剛在我的控制檯上做了這個: 'string =「the.flash.2014.118.hdtv-lol.mp4」' 'pattern2 = re.compile('[\。\ - ] \ d {3,4 }')' 'string =「the.flash.2014.118.mp4」' 'result = pattern2.search(string)' 'result' '<_sre.SRE_Match object; span =(9,14),match ='。2014'>' – Thustra

回答

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' 
+0

這不會工作,不幸的是,它不會總是一個.mp4文件,可能有118和.mp4之間的東西 這是另一個例子:castle.2009.723.x264.mp4 另外findall返回字符串,我希望能找到所有的matchObject。看起來像'finditer()'這樣做,但我不確定你可以在迭代之前檢查迭代中有多少對象。 – Thustra

+0

您可以通過將迭代器轉換爲列表來擴展迭代器:'matches = list(re.finditer(...))'。這樣你就可以知道會有多少比賽。 –

+0

很酷,可能會工作:)如果你把它扔在你原來的答案,我會把它標記爲接受 – Thustra

相關問題