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

fre*_*ate 10 regex mysql diacritics accent-insensitive

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

基本查询如下所示:

SELECT * FROM `table` WHERE `wine_name` REGEXP '[[:<:]]Faugères[[:>:]]'
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM `table` WHERE `wine_name` REGEXP '[[:<:]]Faugeres[[:>:]]'
Run Code Online (Sandbox Code Playgroud)

反其道而行之.

我原以为:

SELECT * 
FROM `table` 
WHERE `wine_name` REGEXP '[[:<:]]Faug[eèêéë]r[eèêéë]s[[:>:]]'
Run Code Online (Sandbox Code Playgroud)

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

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

有什么建议?!

Álv*_*lez 5

你运气不好:

警告

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

[[:<:]][[:>:]]正则表达式运算符是单词边界标记.您可以与LIKE运营商达成的最接近的是:

SELECT *
FROM `table`
WHERE wine_name = 'Faugères'
   OR wine_name LIKE 'Faugères %'
   OR wine_name LIKE '% Faugères'
Run Code Online (Sandbox Code Playgroud)

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

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

你当然不幸:)


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

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