2012-04-02 13 views
5

Mam wiele ciągów, które chcę dopasować podobieństwa (każdy ciąg ma średnio 30 znaków). Znalazłem świetny do tego zadania, ponieważ było to proste i stwierdził, że wyniki są dobre. Ale jeśli porównać hellboy i hell-boy jak tenDokonywanie sequelMatcher difflib ignorować "śmieci" znaków

>>> sm=SequenceMatcher(lambda x:x=='-','hellboy','hell-boy') 
>>> sm.ratio() 
0: 0.93333333333333335 

chcę takie słowa dać 100 procent mecz tj ratio of 1.0. Rozumiem, że znak śmieciowy określony w powyższej funkcji nie jest używany do porównywania, ale znajduje najdłuższy ciągły pasujący podciąg. Czy jest jakiś sposób, aby ustawić SequenceMatcher, aby zignorować niektóre "śmieciowe" znaki w celu porównania?

+3

To rodzaj hackish , ale jakikolwiek powód nie mógł po prostu usunąć znaków _junk_ przed wykonaniem porównania? To w zasadzie to samo, co ich ignorowanie. –

+0

Tak, to dobrze, ale chciałem dowiedzieć się, czy mogę po prostu zrobić magię 'difflib' i uciec z nim w przeciwnym razie musiałbym przekazać ciąg przez inną funkcję, aby najpierw usunąć wszystkie znaki śmieciowe. – lovesh

Odpowiedz

4

Jeśli chcesz zrobić jak sugeruje się w komentarzach, (usunięcie śmieci znaków) najszybsza metoda jest używać str.translate().

Np:

to_compare = to_compare.translate(None, {"-"}) 

Jak pokazano here, to istotnie (3x) szybciej (i czuję ładniejszy czytać) niż regex.

Zauważ, że w Pythonie 3.x lub jeśli używasz Unicode w Pythonie 2.x, to nie zadziała, ponieważ parametr delchars nie jest akceptowany. W takim przypadku wystarczy wykonać mapowanie na Brak. Np:

translation_map = str.maketrans({"-": None}) 
to_compare = to_compare.translate(translation_map) 

Można również mieć małą funkcję zaoszczędzić trochę pisania, jeśli masz wiele postaci, które chcesz usunąć, po prostu zrobić zestaw i przechodzą przez:

def to_translation_map(iterable): 
    return {key: None for key in iterable} 
    #return dict((key, None) for key in iterable) #For old versions of Python without dict comps. 
1

Jeśli było utworzyć funkcję, aby usunąć wszystkie charakter śmieci przed ręką można użyć Re:

string=re.sub('-|_|\*','',string) 

dla wyrażenia regularnego '-|_|\*' prostu umieścić | pomiędzy wszystkimi postaciami śmieci i jeśli jego charakter szczególny re umieścić \ przed nim (jak * i +)