2013-03-18 17 views
7

Mam następujący problem dopasowania potrzebnych danych z nazwami tak:pyton grupa regex opcja przechwytywania

miniseries.season 1.part 5.720p.avi 
miniseries.part 5.720p.avi 
miniseries.part VII.720p.avi  # episode or season expressed in Roman numerals 

W „sezon XX” klocek mogą lub nie mogą występować lub mogą być napisane w skróconej formie, jak „s 1” lub „mórz 1”

W każdym razie chciałbym mieć 4 grupy przechwytywania dając na wyjściu:

group1 : miniseries 
group2 : 1 (or None) 
group3 : 5 
group4 : 720p.avi 

Więc pisałem regex tak:

(^.*)\Ws[eason ]*(\d{1,2}|[ivxlcdm]{1,5})\Wp[art ]*(\d{1,2}|[ivxlcdm]{1,5})\W(.*$) 

Działa to tylko wtedy, gdy mam pełną nazwę pliku, w tym opcjonalny ciąg "sezon XX". Czy można napisać wyrażenie, które zwróci "Brak" jako grupę 2, jeśli "sezon" nie zostanie znaleziony?

Odpowiedz

29

Łatwo jest na tyle, aby grupy sezon opcjonalnie:

(^.*?)(?:\Ws(?:eason)?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art)?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$) 

użyciem grup nie przechwytujące ((?:...)) plus 0 lub 1 kwantyfikator (?). Musiałem sprawić, by pierwsza grupa nie była chciwa, aby zapobiec dopasowaniu jej nazwy do sekcji season.

Zrobiłem również opcjonalne ciągi eason i art w niezapisywanych opcjonalnych grupach zamiast klasach znaków.

Wynik:

>>> import re 
>>> p=re.compile(r'(^.*?)(?:\Ws(?:eason)?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art)?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)', re.I) 
>>> p.search('miniseries.season 1.part 5.720p.avi').groups() 
('miniseries', '1', '5', '720p.avi') 
>>> p.search('miniseries.part 5.720p.avi').groups() 
('miniseries', None, '5', '720p.avi') 
>>> p.search('miniseries.part VII.720p.avi').groups() 
('miniseries', None, 'VII', '720p.avi') 
+0

jestem nowicjuszem o regex, a ja robisz źle staramy się opcjonalny «sezon» i numer razem, zamiast niż osobno – user2181741

Powiązane problemy