Ho un'applicazione che implementa la ricerca incrementale. Ho un catalogo di stringhe unicode da abbinare e abbinarle a una determinata stringa "chiave"; una stringa di catalogo è un "hit" se contiene tutti i caratteri nella chiave, nell'ordine, ed è classificata meglio se i caratteri chiave si raggruppano nella stringa del catalogo.Come implementare la corrispondenza delle stringhe Unicode piegando in python
In ogni caso, questo funziona bene e corrisponde esattamente unicode, in modo che "öst" corrisponderà "Öst Blocket" o "r öst" o "r ö d st en".
In ogni caso, ora voglio implementare la piegatura, poiché ci sono alcuni casi in cui non è utile distinguere tra un carattere di catalogo come "á" o "é" e il carattere chiave "a" o "e".
Ad esempio: "Ole" deve corrispondere "Olé"
Come faccio meglio attuare questo matcher unicode-pieghevole in Python? L'efficienza è importante dal momento che devo abbinare migliaia di stringhe di catalogo alla chiave breve data.
Non deve trasformarlo in ascii; infatti, la stringa di output dell'algoritmo potrebbe essere unicode. Lasciare un personaggio dentro è meglio che spogliarlo.
Non so quale risposta accettare, poiché uso un po 'di entrambi. Prendendo la decomposizione NKFD e rimuovendo i segni combinati va quasi il modo di finire, aggiungo solo alcune traslitterazioni personalizzate a questo. Ecco il modulo come appare ora: (Attenzione, contiene caratteri Unicode in linea, dal momento che è molto più bello di modificare in questo modo.)
# -*- encoding: UTF-8 -*-
import unicodedata
from unicodedata import normalize, category
def _folditems():
_folding_table = {
# general non-decomposing characters
# FIXME: This is not complete
u"ł" : u"l",
u"œ" : u"oe",
u"ð" : u"d",
u"þ" : u"th",
u"ß" : u"ss",
# germano-scandinavic canonical transliterations
u"ü" : u"ue",
u"å" : u"aa",
u"ä" : u"ae",
u"æ" : u"ae",
u"ö" : u"oe",
u"ø" : u"oe",
}
for c, rep in _folding_table.iteritems():
yield (ord(c.upper()), rep.title())
yield (ord(c), rep)
folding_table = dict(_folditems())
def tofolded(ustr):
u"""Fold @ustr
Return a unicode str where composed characters are replaced by
their base, and extended latin characters are replaced by
similar basic latin characters.
>>> tofolded(u"Wyłącz")
u'Wylacz'
>>> tofolded(u"naïveté")
u'naivete'
Characters from other scripts are not transliterated.
>>> tofolded(u"Ἑλλάς") == u'Ελλας'
True
(These doctests pass, but should they fail, they fail hard)
"""
srcstr = normalize("NFKD", ustr.translate(folding_table))
return u"".join(c for c in srcstr if category(c) != 'Mn')
if __name__ == '__main__':
import doctest
doctest.testmod()
(E, per l'abbinamento effettiva se che gli interessi a nessuno: costruisco piegato corde per tutto il mio catalogo in anticipo, e mettere le versioni piegati nella proprietà catalogo degli oggetti alias già disponibili)
Questo è davvero interessante e sarà probabilmente estremamente utile per il completamento automatico dei nomi di persone, poiché la maggior parte delle persone non si preoccuperà di introdurre accenti durante la ricerca di nomi. Sto facendo ricerche su come fare qualcosa di simile in Java. Questo sembra gestire alcuni casi: http://java.sun.com/javase/6/docs/api/java/text/Collator.html. –
sì. Nota che potresti voler omettere 'ü, å, ä, ö' dalla tabella dei casi speciali sopra se vuoi che diventino semplicemente spogliati di accento. Quelle espansioni diftang era quello che volevo dal mio POV (più correttamente degradando il mio linguaggio); ci sono sfortunate eccezioni in altre lingue a tutte queste cose (spagnolo ü per esempio). – u0b34a0f6ae