繁体   English   中英

MySQL REGEXP查询 - 重音不敏感搜索

[英]MySQL REGEXP query - accent insensitive search

我正在寻找一个葡萄酒名称的数据库,其中许多包含重音(但不是统一的方式,所以类似的葡萄酒可以输入或不加重音)

基本查询如下所示:

SELECT * FROM `table` WHERE `wine_name` REGEXP '[[:<:]]Faugères[[:>:]]'

这将返回标题中带有'Faugères'的条目,但不会返回'Faugeres'

SELECT * FROM `table` WHERE `wine_name` REGEXP '[[:<:]]Faugeres[[:>:]]'

反其道而行之。

我原以为:

SELECT * 
FROM `table` 
WHERE `wine_name` REGEXP '[[:<:]]Faug[eèêéë]r[eèêéë]s[[:>:]]'

可能会做的伎俩,但这只返回没有重音的结果。

该字段被整理为utf8_unicode_ci,从我读过的内容是它应该如何。

有什么建议?!

你运气不好

警告

REGEXP和RLIKE运算符以字节方式工作,因此它们不是多字节安全的,并且可能会产生多字节字符集的意外结果。 此外,这些运算符通过字节值比较字符,并且即使给定的排序规则将重音字符视为相等,重音字符也可能无法比较。

[[:<:]][[:>:]]表达式运算符是字边界的标记。 使用LIKE运算符可以实现的最接近的就是这一行:

SELECT *
FROM `table`
WHERE wine_name = 'Faugères'
   OR wine_name LIKE 'Faugères %'
   OR wine_name LIKE '% Faugères'

正如你所看到的那样,它并不完全等价,因为我已经将字边界的概念限制在空格中。 为其他边界添加更多子句将是一团糟。

您也可以使用全文搜索(尽管它不相同)但您无法在InnoDB表中定义全文索引(尚未)。

你当然不幸:)


附录:从MySQL 8.0开始,这已经改变了:

MySQL使用国际Unicode组件(ICU)实现正则表达式支持,ICU提供完整的Unicode支持并且是多字节安全的。 (在MySQL 8.0.4之前,MySQL使用Henry Spencer的正则表达式实现,它以字节方式运行,并且不是多字节安全的。

因为REGEXP和RLIKE是面向字节的,你试过:

SELECT 'Faugères' REGEXP 'Faug(e|è|ê|é|ë)r(e|è|ê|é|ë)s';

这说明其中一个必须在表达中。 请注意,我没有使用加号(+),因为这意味着一个或多个。 既然你只想要一个,你不应该使用加号。

utf8_general_ci在排序时看到重音/没有重音之间没有区别。 也许这对搜索也是如此。 另外,将REGEXP更改为LIKE。 REGEXP进行二进制比较。

好的,我在搜索其他内容时偶然发现了这个问题。

这返回true。

SELECT 'Faugères' REGEXP 'Faug[eèêéë]+r[eèêéë]+s';

希望能帮助到你。

添加'+'告诉正则表达式查找一个或多个字符。

为了解决这个问题,我尝试了不同的东西,包括使用二进制关键字或latin1字符集但无济于事。
最后,考虑到它是一个MySql错误,我最终取代了é和èchars,

像这样 :

SELECT * 
FROM `table` 
WHERE replace(replace(wine_name, 'é', 'e'), 'è', 'e') REGEXP '[[:<:]]Faugeres[[:>:]]'

我有同样的问题试图找到符合下列模式之一的每条记录:'copropriété','copropriete','COPROPRIÉTÉ','Copropri?t?'

REGEXP 'copropri.{1,2}t.{1,2}为我工作。 基本上, .{1,2}将在每种情况下工作,字符是1或2字节编码。

说明: https//dev.mysql.com/doc/refman/5.7/en/regexp.html

警告
REGEXP和RLIKE运算符以字节方式工作,因此它们不是多字节安全的,并且可能会产生多字节字符集的意外结果。 此外,这些运算符通过字节值比较字符,并且即使给定的排序规则将重音字符视为相等,重音字符也可能无法比较。

我有这个问题,并且去了Álvaro的建议。 但就我而言,它错过了搜索词是字符串中间词的那些实例。 我去了相当于:

SELECT *
FROM `table`
WHERE wine_name = 'Faugères'
   OR wine_name LIKE 'Faugères %'
   OR wine_name LIKE '% Faugères'
   OR wine_name LIKE '% Faugères %'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM