1

我在 Python3 中创建了这个 NOACCENT COLLATION,以便在我正在尝试编写的 sqlite 数据库程序中使用它。

我的目标是使带重音的人声搜索不敏感,并使数据输入对重音也不敏感,这样(即)如果该表字段中已经存在“Gonzalez”值,则不会承认“Gonzalez”值。

我所做的对第二部分(限制值)和完整的值搜索很有效。我无法使它适用于 SELECT ... LIKE 表达式。我知道 SQLite 中 COLLATE NOCASE 对 az, AZ 中的 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')

没有重音的值。

数据库本身是否有任何解决方案,或者我必须通过软件进行部分搜索(即“阿尔伯特”)。

希望我的问题足够清楚。

提前致谢。


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
4

2 回答 2

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 请注意,我不是专业人士,在某些情况下,个性化的“喜欢”可能会导致错误。正则表达式必须改进,但对于我们在图书馆数据库中的使用,它已经工作多年了。如果您改进了这项工作,请分享。

于 2017-12-04T10:15:11.493 回答
0

LIKE 忽略排序规则,并始终使用 ASCII 规则。

如果要将 LIKE 模式匹配与其他排序规则一起使用,则必须将文本的规范化形式存储在另一列中。

于 2014-11-11T20:45:35.123 回答