У меня есть приложение, реализующее инкрементный поиск. У меня есть каталог строк юникода, который нужно сопоставить, и сопоставлять их с данной «ключевой» строкой; строка каталога является «хитом», если она содержит все символы в ключе, по порядку, и она лучше оценивается, если кластер ключей кластер в строке каталога.Как реализовать соответствие строк в Unicode, складывая в python
В любом случае, это работает отлично и соответствует Юникоду точно, так что "ОСТ" будет соответствовать "ОСТУ blocket" или "г ОСТА" или "R ö d я ы".
В любом случае, теперь я хочу реализовать фальцовку, поскольку есть некоторые случаи, когда нецелесообразно различать символ каталога, такой как «á» или «é», и ключевой символ «a» или «e».
Например: «Ole» должен соответствовать «оле»
Как лучше реализовать этот Юникод складных Искателя в Python? Эффективность важна, поскольку мне приходится сопоставлять тысячи строк каталога с коротким заданным ключом.
Не нужно превращать его в ascii; Фактически, выходная строка алгоритма может быть unicode. Оставить персонажа лучше, чем лишить его.
Не знаю, какой ответ принять, так как я использую немного обоих. Принимая декомпозицию NKFD и удаляя комбинации меток, вы почти закончите, я добавлю к ним некоторые пользовательские транслитерации. Вот модуль, как он выглядит сейчас: (Внимание, содержит юникод символы рядный, так как это намного лучше, чтобы изменить этот путь.)
# -*- 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()
(А, для фактического соответствия, если это интересует никого: я конструкт сложенный струны для всего моего каталога заранее, и поставить согнутые версии в уже имеющейся недвижимости Каталог объектов псевдонима)
Это действительно круто и, вероятно, будет чрезвычайно полезно для автозаполнения имен людей, так как большинство людей не захотят вводить акценты при поиске имен. Я изучаю, как сделать что-то подобное на Java. Кажется, что это касается некоторых случаев: http://java.sun.com/javase/6/docs/api/java/text/Collator.html. –
да. Обратите внимание, что вы можете отказаться от «ü, å, ä, ö» из таблицы для особых случаев, если вы хотите, чтобы они просто стали акцентами. Эти расширения дифтонга были тем, что я хотел от моего POV (более правильно унизительным языком); есть несчастливые исключения на других языках для всех таких вещей (например, испанский ü). – u0b34a0f6ae