MySQL: выбор из таблицы на основе формы арабского символа в столбце - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть таблица с арабскими словами, сортировка столбца - utf8_general_ci.Я хочу получить слова на основе формы арабской буквы, а не только самой буквы.

Пример: (ب) это базовая форма письма.исходя из своего места в слове, он будет иметь различные формы, такие как (بـ) или (ـبـ) или (ـب)

Сначала я попытался идентифицировать их в столбце с помощью Unicode, например:

(بـ) = 0xFE91 (Unicode) = 0xEFBA91 (UTF-8)

, используя этот запрос:

SELECT * FROM arabicwords WHERE ArWord = char(0xEFBA91 using utf8)

Здесь есть две проблемы

Во-первых, я нене знаю, как использовать "LIKE" с методом char ().Я попытался гуглить безрезультатно.

Во-вторых, я пытался использовать 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."%' ");

, но это возвращает пустой результат.

Может кто-нибудь сказать мне, что я делаю неправильно или есть лучший способ сделать это.

Спасибо

1 Ответ

0 голосов
/ 12 февраля 2019

Рассмотрим

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'.)

(из комментария ОП:)

Должно совпадать:

مسابح  -- 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 имеет Unicode 9.0 с utf8mb4_0900_ai_ci.Может быть интересно посмотреть, работает ли это по-разному.

Тест, чтобы увидеть, равны ли два разных 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 в начале слова, мы можем продолжить это.

...