gpt4 book ai didi

php - 搜索阿拉伯名称丢弃 "أ"之间的差异, "ا"在 mysql

转载 作者:可可西里 更新时间:2023-11-01 07:04:10 24 4
gpt4 key购买 nike

我将阿拉伯语名称存储在我的数据库中。在阿拉伯语中,有些字母可能以不同的格式书写,例如“ا”、“أ”、“آ”,它们都代表同一个字母。还有,“Ç” Ì “É”。

我需要在数据库中搜索名称并忽略“ا”、“أ”、“آ”之间的差异以及“Ç”和“⑩”之间的差异。

因此,例如,当用户在搜索框中输入“اسام٩”时,它应该返回“أسام٩”、“اسامة”、“أسامه،”اسامه ... 等。另一个例子,“فايò”、“́ائ”应该返回两个.

我如何使用 mysql 查询来做到这一点?如何搜索相似的名称而不是相同的名称?

我尝试了 Like 关键字,但它不起作用。

select * from employee WHERE fname like "%أسامة%" and mname="علي" and lname="الجاسم"

最佳答案

更新:我重写了我的答案,以防有人需要解决方案并偶然发现这个问题。

对于这个问题,我知道有 3 种可能的解决方案:

  1. 创建自定义排序规则
  2. 添加规范化字段
  3. 在查询中使用正则表达式

我写了一个tutorial展示如何将这些解决方案应用于 MySQL。我将在此处尝试总结这些步骤。

<强>1。创建自定义排序规则

您可以创建自定义排序规则,使 MySQL 将这些字符作为一个字符来处理。可以将自定义排序规则添加到名为 Index.xml 的文件中位于字符集目录中。可以通过查询 information_schema 找到文件的位置。具有以下内容:

SHOW VARIABLES LIKE 'character_sets_dir';

导航到目录,备份文件,打开它并滚动到元素<charset name=”utf8″> , 添加以下 XML:

<charset name="utf8">
.
.
.
<collation name="utf8_arabic_ci" id="1029">
<rules>
<reset>\u0627</reset> <!-- Alef 'ا' -->
<i>\u0623</i> <!-- Alef With Hamza Above 'أ' -->
<i>\u0625</i> <!-- Alef With Hamza Below 'إ' -->
<i>\u0622</i> <!-- Alef With Madda Above 'آ' -->
</rules>
<rules>
<reset>\u0629</reset> <!-- Teh Marbuta 'ة' -->
<i>\u0647</i> <!-- Heh 'ه' -->
</rules>
<rules>
<reset>\u0000</reset> <!-- Ignore Tashkil -->
<i>\u064E</i> <!-- Fatha 'َ' -->
<i>\u064F</i> <!-- Damma 'ُ' -->
<i>\u0650</i> <!-- Kasra 'ِ' -->
<i>\u0651</i> <!-- Shadda 'ّ' -->
<i>\u064F</i> <!-- Sukun 'ْ' -->
<i>\u064B</i> <!-- Fathatan 'ً' -->
<i>\u064C</i> <!-- Dammatan 'ٌ' -->
<i>\u064D</i> <!-- Kasratan 'ٍ' -->
</rules>
</collation>
</charset>

这个 xml 只是说这个排序规则是 utf8 字符集之一,我选择将它命名为 utf8_arabic_ci , 并选择 ID 号 1029 , custom collations ids are in the range 1024-2047 .归类规则告诉 MySQL 将所有形式的 Alef 以及 Teh 和 Heh 视为相同的字符,并完全忽略 tashkil。如果您愿意,可以添加更多规则。引用MySQL docuemntation for more info about custom collations .

现在重新启动 MySQL 并将列的排序规则更改为我们使用如下查询的新排序规则:

ALTER TABLE persons MODIFY name VARCHAR(50) 
CHARACTER SET 'utf8' COLLATE 'utf8_arabic_ci';

您应该能够搜索“اسام٩”并获得“اسام٩”、“أسامه”、“أسَامو”……等。

<强>2。添加规范化字段

此解决方案需要向表中添加一个新字段。该字段将被“规范化”,这是规范化阿拉伯名字字段的示例:

id normalized_name name
1 احمد احمد
2 أحمد احمد
3 أسامه اسامة
4 أسامة اسامة
5 اسامه اسامة
6 اسَامه اسامة

可以通过向表中添加一个新列并用“规范化”函数的结果填充它来创建此规范化字段,该函数仅用一个替换字符的不同变体并删除 Tashkil。现在要使搜索查询正常工作,我们将查询规范化字段并显示原始字段。类似于以下内容:

SELECT name FROM persons WHERE normalized_name = "اسامة";

+--------------+
| name |
+--------------+
| أسامه |
| أسامة |
| اسامه |
| اسَامه |
+--------------+

<强>3。在查询中使用正则表达式

我不推荐这个解决方案,你会失去索引的优势,会降低性能,而且你会很难生成正则表达式模式。但您可能会发现它对测试或特殊查询很有用。

您可以使用 REGEX或其同义词 RLIKE在 MySQL 查询中。例如,如果您想查找名称“أحمد”与 Alef 的任何变体,您将使用如下模式:

SELECT name FROM clients WHERE name REGEXP 'ا|أ|إ]حمد]'

这应该会显示所需的结果,您所要做的就是编写一个函数来为搜索字符串生成此模式。这是一个示例函数,但请记住这只是一个示例,并不适用于所有情况:

// Add all your patterns and replacement in these arrays
$patterns = array( "/(ا|أ|آ)/", "/(ه|ة)/" );
$replacements = array( "[ا|أ|آ]", "[ة|ه]" );
$query_string = preg_replace($patterns, $replacements, $search_string);

这应该适用于 Alef、Teh 和 Heh,但不适用于 Tashkil。

结论

添加自定义排序规则我认为是大多数情况下的最佳解决方案,但您可能无法编辑字符集文件(例如,如果您使用的是共享主机),添加规范化字段将是解决方案大小写,您可能会发现正则表达式模式在某些情况下很有用。

关于php - 搜索阿拉伯名称丢弃 "أ"之间的差异, "ا"在 mysql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43443740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com