我在Python3中创建了这个NOACCENT COLLATION,用于我正在尝试编写的sqlite数据库程序。
我的目标是使重音的人声不敏感搜索,并使数据输入对重音也不敏感,以便(即)如果该表字段中已存在'Gonzalez'值,则不会接受值'González'。 / p>
我所做的对于第二部分(限制值)和完整的值搜索非常有效。 我不能使它适用于SELECT ... LIKE表达式。我知道SQLite中的COLLATE NOCASE对于a-z,A-Z中的unicode字符的LIKE限制但是当我使用我自己定义的排序规则NOACCENT时,为什么会出现这种限制?因为这似乎正是发生的事情。
示例:
cur.execute(""" CREATE TABLE Demo(
Id INTEGER PRIMARY KEY,
Nombre TEXT COLLATE NOACCENT UNIQUE)""")
cur.execute("INSERT INTO Demo(Nombre) VALUES ('álberto')")
cur.execute("INSERT INTO Demo(Nombre) VALUES ('alberta')")
cur.execute("INSERT INTO Demo(Nombre) VALUES ('Álbertu')")
cur.execute("INSERT INTO Demo(Nombre) VALUES ('Álberte')")
cur.execute("INSERT INTO Demo(Nombre) VALUES ('Albertczo')")
cur.execute("INSERT INTO Demo(Nombre) VALUES ('albertai')")
如果我这样做:
cur.execute("SELECT * FROM Demo WHERE Nombre='ALBERTO' COLLATE NOACCENT")
我明白了:
(1, 'álberto)
什么都好。这适用于大写和小写的任意组合以及任何单词中的任何重音('ALBERTÓ','Älbèrtô'......)
如果我尝试插入值'ALBERTÓ',由于唯一约束我会收到错误,因此效果很好。
问题是当我尝试使用LIKE表达式时:
cur.execute("SELECT * FROM Demo WHERE Nombre LIKE 'ALBERT%' COLLATE NOACCENT")
返回:
(2, 'alberta')
(5, 'Albertczo')
(6, 'albertai')
没有重音的值。
数据库本身是否有任何解决方案,或者我必须通过软件进行部分搜索(即'albert')。
希望我的问题足够明确。
提前致谢。
def noaccent(string): # eliminate accented vocals
vocals = ['a', 'e', 'i', 'o', 'u'] * 4
acc_vocals = ['á', 'é', 'í', 'ó', 'ú','à', 'è', 'ì', 'ò', 'ù', 'ä', 'ë', 'ï', 'ö', 'ü', 'â', 'ê', 'î', 'ô', 'û']
no_acc = string
for letter in acc_vocals:
no_acc = no_acc.replace(letter, vocals[acc_vocals.index(letter)])
return no_acc
def collate_noaccent(string1, string2):
str1 = noaccent(string1.lower())
str2 = noaccent(string2.lower())
if str1 < str2:
return -1
elif str1 > str2:
return 1
else:
return 0
答案 0 :(得分:1)
我通过在我设计的SqliteUnicode类中创建自己的“like”函数来解决这个问题。它将搜索速度减慢了8倍。由于课程尚未优化,我现在不想在此处发布,除非您提出要求。
link = sqlite.connect(db_file_s)
extension = SqliteUnicode()
link.create_collation("france", extension.collate)
link.create_function("like", 2, extension.like)
编辑2019:您可以在此处找到该课程: https://pastebin.com/FvMZdBY5 请注意,我不是专业人士,并且仍然存在个性化“喜欢”可能导致错误的一些情况。必须改进正则表达式,但是对于我们在库数据库中的使用,它现在可以正常工作多年。如果你改进这项工作,请分享。
答案 1 :(得分:0)
LIKE忽略排序规则,并始终使用ASCII规则。
如果您想使用LIKE模式匹配其他排序规则,则必须store a normalized form of the text in another column。