【问题标题】:Stripping MySQL queries of foreign accents去除外国口音的 MySQL 查询
【发布时间】:2016-03-18 06:19:52
【问题描述】:

我必须承认我对php一无所知,而且我现在的脚本是继承的......

它使用 city 名称查询 MySQL 数据库,并返回它找到的 city 的所有实例。

我遇到了几个问题:第一个与连字符有关(例如 Stratford-upon-Avon);已通过添加

解决
$searchq = str_replace( '-', ' ', $searchq );

这让我可以在没有连字符的情况下在数据库中输入数据。

我剩下的问题与外国口音有关(特别是:accent、grave、circumflex、cedille、tilde)。我尝试了上百万个函数,其中很多是我在这个网站上找到的,但都无法正常工作。

我当前页面的主要php代码是这样的

$searchq = filter_var("%{$_POST['keyword']}%", FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH); // Sanitize the string

$searchq = str_replace('-', '', $searchq);

$sql = "SELECT Image, Chain, Country, City, Top as '', Medium as '', Low as '' FROM Chains WHERE Country LIKE ? OR City LIKE ?"; // Your query string

$prepare = $mysqli->prepare($sql); // Prepare your query string
$prepare->bind_param('ss', $searchq, $searchq); // Bind the placeholders to your search variables
// s = string | i = integer | d = double | b = blob
$prepare->execute(); // Execute the prepared statement
$prepare->store_result(); // Store the results for later checking

我没有参加这个论坛,因为我知道它是为高级开发人员准备的,我不是其中之一......

以上代码所做的只是删除重音字母,而不是用没有重音符号的相同字母替换它

编辑

如何再次引起 Ollie Jones 的注意?

我被卡住了,不知道如何处理脚本部分

另一个编辑 当我在表 SQL 中输入它时

ALTER TABLE Chains CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8_general_ci;

我收到此警告,但什么都没做...

#1253 - COLLATION 'utf8_general_ci' 对 CHARACTER SET 'utf8mb4' 无效

【问题讨论】:

  • 你在这里很好。欢迎来到 Stackoverflow。你究竟为什么要摆脱所有这些特殊字符?你的数据库不能也包含它们吗?
  • 以法国小镇“Sèvres”为例。像数据库中的许多其他人(1000s)一样,我不想同时有口音和没有口音。所以数据库有“Sevres”,如果有人写了正确的词,那一刻的回复是“Nothing found”......
  • 让我在最后一条评论中添加关于带和不带重音输入数据库的内容。以简单的词“Sèvres”(坟墓)为例。像我这样的人可能会写“Sévres”(急性)。其他人习惯用谷歌搜索写“Sevres”(没有口音)。这就是简单的情况。在更复杂的情况下,您可能有 2 个不同的标志(重音和回音;锐音和 cedilla);那么你会得到一些由两个或三个单词组成的单词,并为所有组合和可能的错误腾出空间,你最终会付出大量的工作和混乱......“简单”的出路是得到一个删除所有重音的脚本。
  • 拿“简历”或让它更有趣的“tête-à-tête”......
  • 数据库中最好有两列,一列是带有重音符号和变音符号的实际名称,第二列是没有的。一旦有人输入了一个单词,您就会删除代码中的特殊字符并搜索该条目是否存在(基于 unaccented/slug 列)并使用它。这样您就可以显示重音版本并按非重音搜索。

标签: php mysql diacritics


【解决方案1】:

MySQL 的字符集和整理功能旨在正确处理此类事情,而无需额外的搜索列。

例如,观察这个小查询:

select _utf8'résumé' COLLATE utf8_general_ci = _utf8'resume'

或者,使用更现代的 utf8mb4 字符集,

select _utf8mb4'résumé' COLLATE utf8mb4_general_ci = _utf8mb4'resume'

这两个查询都发现résumé 和resume 相等。它适用于几乎所有欧洲语言的重音字符。

这些查询包含两个明确创建为 unicode 字符串的字符串常量。然后它使用 case_insensitive 排序规则对它们进行比较。在该排序规则中,e-acute 和 e-grave 的大小写形式都被认为是相同的。

你如何让它与你的数据库一起工作?

  1. 确保您的地名列(City、Country)的字符集设置为utf8,或者更好的是,更强大和现代的utf8mb4。

  2. 确保这些表的默认排序规则是您选择的字符集的不区分大小写的排序规则。

  3. 只需进行查询即可。你不需要任何特别的东西。例如,WHERE City = 'Sèvres' 和 WHERE City = 'sevres' 将产生相同的结果。这非常适合习惯于使用 Google 类型搜索的用户。

在改变你的桌子之前做一个备份,以防你搞砸了。

CREATE TABLE chains_backup SELECT * FROM chains

然后使用这种命令来更改表格中的列。

  alter table chains
       modify City  varchar(255)
                    character set utf8mb4
                    collate utf8mb4_general_ci

您需要使用列的实际数据类型来代替varchar(255)。你没有告诉我们那是什么,所以我猜。

您为每个列选择的默认排序规则已包含在索引中。因此,您对变音符号不敏感的搜索不仅准确,而且速度很快。

请注意,西班牙语 ñ 是一个奇怪的例子。与一般排序规则ñ 和n 相等。但在西班牙语词典中,ñ 是一个不同的字母。因此,如果您想要按字母顺序排列西班牙地名,则需要 utf8_spanish_ci 或 utf8mb4_spanish_ci 排序规则。

问题中显示的代码的好消息是:当您使用不区分大小写的排序规则时,您根本不需要 just_clean 函数。

您可能希望使用WHERE City LIKE 'stratford%' 而不是WHERE City = 'stratford' 进行搜索——这将允许您的查询匹配搜索词的前几个字符。 LIKE 构造将匹配 Stratford-upon-Avon 以及 Stratfordshire。

【讨论】:

  • 嗨 Ollie 在我这个年纪,我需要深呼吸...表格问题看起来很简单,但我该怎么处理脚本,因为上面代码中的函数只是我尝试插入。我可以发布实际代码和表结构,但我该怎么做呢?下方的“回答您的问题”按钮?
  • 不要使用“回答”向您的问题添加信息,您的问题上有一个编辑按钮:D
  • 我可以上传一个 .png 和一个 .zip 文件吗?
  • 我对你的 3 点有点困惑。 1) utf8 似乎是默认值,并没有改变任何东西:2) 似乎是这样工作的,因为我可以输入任何一种方式,无论是否大写 3) 你说我不需要做任何事情,但它没有按我的方式工作......我必须在脚本中做一些事情。没有?
  • 嗨奥利。我已经继续使用复制表进行测试。我做了备份并应用了您在上面发布的修改代码。 'City' 从 text 更改为 varchar (255):看不到任何其他更改。然后我在脚本中更改了表的名称并使用 Sèvres 进行了测试。结果:没有!我究竟做错了什么?您是否通过我上面发布的网址看到了我的脚本?
猜你喜欢
  • 2023-04-08
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
相关资源
最近更新 更多