我有一个阿拉伯语单词表,列的整理是utf8_general_ci。我想根据阿拉伯字母的形状检索单词,而不仅仅是字母本身。
例如:(ب)这是这封信的基本形式。基于它在单词中的位置,它将具有不同的形状,如(ب)或(ب)或(ب)
首先,我尝试使用unicode Ex在列中标识它们:
(ب)= 0xFE91(unicode)= 0xEFBA91(UTF-8)
使用此查询:
SELECT * FROM arabicwords WHERE ArWord = char(0xEFBA91 using utf8)
这里有两个问题
首先,我不知道如何使用char()方法使用“LIKE”。我试图谷歌它没有结果。
其次,我尝试使用php来避免LIKE的问题。
$string ="U+FE91";
$utf8string = html_entity_decode(preg_replace("/U\+([0-9A-F]{4})/", "&#x\\1;", $string), ENT_NOQUOTES, 'UTF-8');
$query = mysqli_query($connection, "SELECT * FROM arabicwords WHERE ArWord LIKE '%".$utf8string."%' ");
但是这会返回一个空结果。
任何人都可以告诉我我做错了什么或者是否有更好的方法来做到这一点。
谢谢
考虑
WHERE HEX(word) REGEXP '^(..)*EFBA91'
说明:
^ -- anchor at start of string
(..)* -- any number of 2-byte pairs, namely hex pairs making up a character
EFBA91 -- match the hex for "beh initial form"
如果,通过“初始”,这只是在'单词'的开头,那么这将起作用,并且更有效:
WHERE HEX(word) LIKE 'EFBA91%'
这可能效率更高,假设它按预期工作:
WHERE word LIKE UNHEX('EFBA9125')
(注意:HEX('%')='25'。)
(来自OP的评论:)
应该匹配:
مسابح -- D985 D8B3 D8A7 D8A8 D8AD
ابريق -- D8A7 D8A8 D8B1 D98A D982
برق -- D8A8 D8B1 D982
باسم -- D8A8 D8A7 D8B3 D985
不应该匹配:
طبيب -- D8B7 D8A8 D98A D8A8
كلب -- D983 D984 D8A8
أب -- D8A3 D8A8
مسبح -- D985 D8B3 D8A8 D8AD
由于十六进制根本不同,我们需要依赖于COLLATION
来识别某些BEH与“初始形式BEH”相匹配。 utf8mb4_unicode_520_ci
实现了Unicode版本5.20标准。或许其他人可以破译标准,足以说出5.20如何处理这种情况。
请注意,MySQL 8.0具有带有utf8mb4_0900_ai_ci
的Unicode 9.0。看看它是否有所不同可能会很有趣。
测试两种不同的Behs是否相同:
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_520_ci;
SELECT UNHEX('D8A8') = UNHEX('EFBA91'); -- returns 0 (false)
所以,这些词都不匹配。与版本8.0.15类似:
SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci;
SELECT UNHEX('D8A8') = UNHEX('EFBA91'); -- also false
如果你想在一个单词的开头讨论检查D8A8
,我们可以追求。