簡體   English   中英

Python/PHP SQLite 在 FTS4/FTS5 中查詢波蘭語字母 Ł/ł

[英]Python/PHP SQLite querying Polish letter Ł/ł in FTS4/FTS5

由於 SQLite FTS4/FTS5 tokenizer=unicode61 給了我們:

a=A=ą=Ą=ä=Ä ...
z=ż=ź=Z=Ż=Ź=Ž=ž ...
etc...

為什么不是 l=ł=L=Ł ??? 不是bug嗎?

如何在沒有波蘭字符 ł/Ł 的鍵盤上查詢 SQLite? 例如,查詢名稱 Żabczyński 像“zabczynski” - 得到了結果,但是對於像“wlast”這樣的名稱 Włast - 0 結果(應該是數百個......)和 ł 在其中,例如 '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);
?>

任何的想法? 你不能像 utf8_general_ci、utf8_polish_ci、utf8_unicode_ci 那樣在 sqlite 中設置編碼......或者是的,有可能嗎?

有沒有辦法在 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列中搜索; 如果它們在那里,它會找到“Żabczyński”、“Zabczynski”、“Żabczynski”和“Zabczynski”。 如果用戶輸入“Zabczyński”或“Żabczynski”,想必他們應該知道波蘭語,所以在原始列中搜索並且沒有返回結果。 所有這些勝利都是以僅存儲一個列的副本為代價的。

轉移到 MySQL 或 Postgres。 SQLite 有其局限性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM