2012-04-02 7 views
5

Ho un sacco di stringhe che voglio associare per similarità (ogni stringa ha in media 30 caratteri). Ho trovato difflib'sSequenceMatcher ottimo per questo compito poiché era semplice e ho trovato i risultati positivi. Ma se confronto hellboy e hell-boy come questofacendo in modo che SequenceMatcher di difflib ignori i caratteri "junk"

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

voglio tali parole per dare una corrispondenza del 100 per cento vale a dire ratio of 1.0. Comprendo che il carattere di rifiuto specificato nella funzione sopra non viene utilizzato per il confronto ma per trovare la sottosequenza di corrispondenza contigua più lunga. Esiste un modo per far sì che SequenceMatcher ignori alcuni caratteri "indesiderati" a scopo di confronto?

+3

E 'una specie di hacker , ma per qualsiasi motivo non è possibile rimuovere i caratteri _junk_ prima di fare il confronto? È essenzialmente la stessa cosa che ignorarli. –

+0

sì, va bene ma volevo capire se potevo semplicemente fare un po 'di difflib' magia e farla franca altrimenti dovrei passare la stringa attraverso un'altra funzione per rimuovere prima tutti i caratteri junk. – lovesh

risposta

4

Se si desidera fare come ho suggerito nei commenti, (togliendo le spazzatura caratteri) il metodo più veloce è utilizzare str.translate().

es:

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

Come mostrato here, questo è significativamente (3x) più veloce (e mi sento più bello da leggere) di un'espressione regolare.

Si noti che in Python 3.x, o se si utilizza Unicode in Python 2.x, questo non funzionerà poiché il parametro delchars non è accettato. In questo caso, è sufficiente effettuare una mappatura su Nessuno. Ad esempio:

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

Si potrebbe anche avere una piccola funzione per risparmiare qualche digitazione se si dispone di un sacco di caratteri che si desidera rimuovere, basta fare un set e passare attraverso:

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

Se si dovesse fare una funzione per rimuovere tutto il carattere spazzatura prima di mano si può usare re:

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

per l'espressione regolare '-|_|\*' basta mettere un | tra tutti i caratteri spazzatura e se un carattere speciale ri mettere un \ prima di esso (come * e +)

Problemi correlati