Piszę program w Pyqt, który musi wziąć brudne struny i oczyścić je. Możliwe wartości wejściowe są niezwykle zmienne. Na przykład chciałbym wziąć ciągi:

"Seven_Pounds_(BDrip_1080p_ENG-ITA-GER)_Multisub_x264_bluray_.mkv",  
"The_Birds_1963_HDTV_XvidHD_720p-NPW.avi",  
"1892.XVID.AC3.HD.120_min.avi"  

I obróć je:
"Siedem funtów",
"Ptaki",
"1892"

Uważałem, że przy użyciu realizacji wyrażeń uciekają, ale ta metoda wydaje się prawdopodobnie zawieść na ostatni przykład. Program Media Gerbil wykorzystuje Algorytm Google Diff-Mecz algorytm do czynienia z czyszczeniem łańcucha. Wydaje się to być lepszą alternatywą, ale nie jestem pewien, jak go wdrożyć. Czy istnieje druga, bardziej efektywna metoda czyszczenia strun w Python / Pyqt, czy jest regex lub poprawa dopasowania najlepsza trasa do śledzenia?

2
dman 6 październik 2011, 22:59

5 odpowiedzi

Najlepsza odpowiedź

Na podstawie twojego przykładu:

import re

a="The_Birds_1963_HDTV_XvidHD_720p-NPW.avi"
b="Seven_Pounds_(BDrip_1080p_ENG-ITA-GER)_Multisub_x264_bluray_.mkv"
c="1892.XVID.AC3.HD.120_min.avi"

def cleanit(str):
    result = []
    l = re.split('[_.]',str)
    flag = 0
    if re.match('^[a-zA-z]+',l[0]):
        flag = 1
    elif re.match('^[0-9]+',l[0]):
        flag = 2

    if flag == 1:
        for x in l:
            if not re.match('^[a-zA-Z]+',x):
                break;
            result.append(x) 
        return " ".join(result)

    if flag == 2:
        for x in l:
            if not re.match('^[0-9]+',x):
                break;
            result.append(x) 
        return " ".join(result)

if __name__ == '__main__':
    print cleanit(a)
    print cleanit(b)
    print cleanit(c)

Wydrukuje:

kent$  python cleanit.py
The Birds
Seven Pounds
1892
2
Kent 6 październik 2011, 19:32

Z wyglądu Diff-Match-Patch, dopasuj, że jest najbliżej tego, o czym mówisz, wydaje mi się, że może to nie jest najlepsze rozwiązanie, ponieważ mecz najwyraźniej chce znaleźć konkretne wzory (nie regex reguły)?

Myślę, że możesz zdefiniować serię reguł regex, takich jak podkreślenie traktowane jak przestrzeń między słowami, a dowolne nie- [A-ZA-Z0-9 _] + prawdopodobnie sygnalizujące koniec tytułu. Musiałbyś przynajmniej założyć założenie, że Twój tytuł rozpoczyna się od początku ciągu, a następnie wzorzec dopasowania do osiągnięcia znaku "nie słowo".

Może coś takiego?

rx = re.compile(r'([a-zA-Z\d_]+[a-zA-Z\d])[_.]?')

Ale niestety, jak wspomniano w innej z tych odpowiedzi, nie ma sposobu, aby naprawdę zajmować się "ptakami 1963". Myślę, że rozwiązanie jest kombinacją przyjęcia, gdzie tytuł powinien rozpocząć i być może zatrzymać i mieć listę wspólnych tagów, które mogłyby zostać usunięte.

edytuj - pomyślałem o więcej informacji

Być może kiedyś zawęziłeś swój potencjalny tytuł, jeśli daleko możesz go zdobyć, możesz zrobić łatkę Google Diff-Match-Patch z może wyszukiwanie API w IMDB.com i znajdź najbliższy mecz do prawdziwego tytułu

2
jdi 6 październik 2011, 19:26

Właściwie to zrobiłem w jednym punkcie ... zasadniczo podążasz za serią kroków

  • Wyeliminuj wszystko w [] 's, ()' s lub {} s
  • Usuń rozszerzenie pliku
  • Teraz podzielony na [.-_]

W twoim przypadku otrzymasz:

Seven Pounds Multisub x264 bluray
The Birds 1963 HDTV XvidHD 720p NPW
1892 XVID AC3 HD 120 min

Teraz zasadniczo przechowujesz listę słów, aby oczyścić z listy, zanim na to spojrzysz. Oczywiste z tego przykładu są X264, Multisub, Bluray, HDTV, XVIDHD, XVID, HD, 720P, 1040P, AC3. Należy pamiętać, że będziesz chciał mieć pewności siebie, porównuje tutaj.

Należy pamiętać, że ta lista rozszerzy ręcznie, gdy przejdziesz przez kolekcję, a to pozostawia cię

Seven Pounds
The Birds 1963
1892 120 min

Jest to prawdopodobnie tak dobre, jak dostaniesz na pół-automatyczny system. Jedną z powyższych metod powie Ci oczyszczenie liczb, które nie pojawiają się z przodu, ale zestąpiłbym, że będziesz zepsuć rzeczy jak "Toy Story 2".

W moim przypadku wykonałem powyższe przetwarzanie, a następnie próbowałem dowiedzieć się, które wzorce katalogowe dopasowane do archiwalu. Potem miałem interfejs oparty na przeklinaniu, który pozwolił mi przewijać i ręcznie poprawić wnioski skryptu (w tym zmiany nazwy).

Edytuj: Na drugiej myśli, mój skrypt faktycznie założył, że zestaw liczb drugi (jak również wszystko potem) może być bezpiecznie usunięte. Są to wszystkie heurystyki, a ty będzie wpadniesz na wyjątki. Dodanie tego kroku poprawiłoby ostatni przykład tytułu do 1892.

2
jkerian 6 październik 2011, 19:44

Ocena od przykładów wygląda na to, że będzie to niezwykle trudne, niezależnie od techniki. Jak powinien wiedzieć, że 1963 nie jest częścią tytułu środkowego filmu? Być może najlepszym zakładem jest posiadanie listy akronimów, a następnie obcięty ciąg z pierwszego dopasowywania akronimu i do przodu. Dałoby ci The Birds 1963, ale naprawdę nie widzę tego.

1
PEZ 6 październik 2011, 19:13

Cięcie przez podkreślenia, spacje, kropki.

Odbieraj oczywiste części, takie jak x264 lub bdrip lub multisub .

Zapytanie IMDB na film z tymi słowami w imię :)

0
9000 6 październik 2011, 19:27