由于 SQLite FTS4/FTS5 tokenizer=unicode61 为我们提供:
a=A=ą=Ą=ä=Ä ...
z=ż=ź=Z=Ż=Ź=Ž=ž ...
etc...
为什么不是 l=ł=L=Ł ???这不是bug吗?
如何在没有波兰语字符 ł/Ł 的键盘上查询 SQLite?例如,查询名称 Żabczynski(如“zabczynski”) - 得到结果,但查询名称 Włast(如“wlast”) - 0 个结果(应该是数百个...) 我在 PHP 中有我的解决方案,但它不适用于其中包含 l 和 ł 的单词,例如“opłacalny”。
<?
$q = $_POST["q"];
//
$pat = '/(\b\w*[lł]\w*\b)/iu';
$q = preg_replace_callback($pat,function($macz){
return "(" . str_replace("ł","l",$macz[1]) . "* OR " . str_replace("l","ł",$macz[1]) . "*)";
},$q);
// so query 'andrzej wlast' looks 'andrzej (wlast* OR włast*)'
...
$sql = "SELECT ...";
$pdo = $db->prepare($sql);
//
$pdo->execute([":q" => "$q*"]);
//
$odp = $pdo->fetchAll(PDO::FETCH_ASSOC);
?>
有什么想法吗?您无法在 sqlite 中设置编码,如 utf8_general_ci、utf8_polish_ci、utf8_unicode_ci...或者是的,这是可能的?
有没有办法用Python解决这个问题?平台上没有 ICU(共享服务器)。
最佳答案
不幸的是,不,SQLite 没有像 MySQL 那样的整理表,因为它会使本来应该是一个非常小且可移植的库变得臃肿。
您可以将查询转换为如下形式:
SELECT * FROM foo WHERE word REGEXP '^[ZŻ]abczy[nń]ski$';
SELECT * FROM foo WHERE word REGEXP '^W[lł]ast$';
在 Python 中这很容易:
def collatify(string, equivalents):
for original, replacement in equivalents.items():
string = string.replace(original, '[%s%s]' % (original, replacement))
return string
collatify('Żabczyński', { "Ż": "Z", "ń": "n" })
同样不幸的是,这将导致无法使用索引对这些字段进行搜索。
更好的方法是执行相反的操作,将字符串“asciify”,并将它们作为附加列输入数据库(具有自己的索引!);然后“asciify”你的查询,并观察它的工作情况。更好的是,看看您的“asciified”查询是否与原始查询相同;如果是,则使用“asciified”列(因为用户仅输入 ASCII 字符);如果它们不同,则用户输入了波兰语特定的字符,并且可能会正确输入它们,因此请使用原始列。这样,如果用户输入“Żabczyński”,您可以在原始列中搜索“Żabczyński”并在那里找到它。如果用户输入“Zabczynski”,假设它可能是asciified,并在asciified列中搜索;如果存在“Żabczynski”、“Zabczynski”、“Żabczynski”和“Zabczynski”,它会找到它们。如果用户输入“Zabczynski”或“Żabczynski”,想必他们应该懂波兰语,因此在原始列中搜索并不会返回任何结果。所有这些胜利都是以只存储一份专栏副本为代价的。
关于php - Python/PHP SQLite 查询 FTS4/FTS5 中的波兰语字母 Ł/ł,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51875063/