13

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

基本查询如下所示:

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

这将返回标题中带有“Faugeres”的条目,但不返回“Faugeres”

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

相反。

我曾想过这样的事情:

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

可能会成功,但这只会返回没有重音的结果。

该字段被整理为 utf8_unicode_ci,从我读过的内容来看,它应该是这样的。

有什么建议么?!

4

7 回答 7

7

你不走运

警告

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

[[:<:]]和regexp 运算符是单词边界的[[:>:]]标记。您可以使用操作员实现的最接近的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) 实现正则表达式支持,它提供完整的 Unicode 支持并且是多字节安全的。(在 MySQL 8.0.4 之前,MySQL 使用 Henry Spencer 的正则表达式实现,它以字节方式运行并且不是多字节安全的。

于 2013-01-03T10:47:37.560 回答
4

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

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

这表示其中之一必须在表达式中。请注意,我没有使用加号(+),因为这意味着一个或多个。由于您只想要一个,因此不应使用加号。

于 2014-11-14T18:26:30.840 回答
1

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

于 2013-01-03T10:49:34.817 回答
0

为了解决这个问题,我尝试了不同的方法,包括使用 binary 关键字或 latin1 字符集但无济于事。
最后,考虑到这是一个 MySql 错误,我最终替换了 é 和 è 字符,

如下所示:

SELECT * 
FROM `table` 
WHERE replace(replace(wine_name, 'é', 'e'), 'è', 'e') REGEXP '[[:<:]]Faugeres[[:>:]]'
于 2014-07-21T17:11:38.473 回答
0

我有这个问题,并在上​​面寻求 Á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 %'
于 2018-05-30T04:47:38.740 回答
0

我在尝试查找与以下模式之一匹配的每条记录时遇到了同样的问题:“copropriété”、“copropriete”、“COPROPRIÉTÉ”、“Copropriété?t?”

REGEXP 'copropri.{1,2}t.{1,2}为我工作。基本上,.{1,2}无论字符是 1 字节还是 2 字节编码,will 都应该适用。

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

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

于 2017-03-29T16:41:52.133 回答
-1

好的,我在寻找其他东西时偶然发现了这个问题。

这返回真。

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

希望能帮助到你。

添加“+”告诉正则表达式查找一个或多个出现的字符。

于 2013-08-16T03:48:03.330 回答