5

当我在 MySQL 中进行 REGEXP 比较时,对于瑞典字符的大写版本,我得到了一些奇怪的结果。我正在使用 utf8_swedish_ci 排序规则,我想找到大写的单词。

SELECT 'Öster' REGEXP BINARY '^[A-ZÅÄÖ][a-zåäö]+$'应该返回 1 并且SELECT 'öster' REGEXP BINARY '^[A-ZÅÄÖ][a-zåäö]+$'应该返回 0,但我得到相反的结果。

SELECT 'Öster' REGEXP BINARY '^[A-ZÅÄÖ][a-zåäö]+$' # returns 0 (incorrect)
SELECT 'öster' REGEXP BINARY '^[A-ZÅÄÖ][a-zåäö]+$' # returns 1 (incorrect)
SELECT 'Söder' REGEXP BINARY '^[A-ZÅÄÖ][a-zåäö]+$' # returns 1 (correct)
SELECT 'söder' REGEXP BINARY '^[A-ZÅÄÖ][a-zåäö]+$' # returns 0 (correct)

如果我使用 REGEXP 而不是 REGEXP BINARY,'söder' 也会匹配(这不是我想要的),但即便如此,'Öster' 也不是匹配的。

我该怎么办?

4

2 回答 2

3

我意识到您已经找到了解决方法,但想解释一下它为什么有效。REGEXP在 MySQL 中不适用于“字符”,但适用于 bytes。Å、Ä、Ö、å、ä 和 ö 都是 UTF-8 中的两个字节字符。当它们在正则表达式[ ]构造中使用时,正则表达式引擎会单独查看这些字节中的每一个,并且只尝试匹配一个字节而不是组成整个字符的两个字节。如果你将这些字符分解成它们的组成字节,你就会明白为什么有些匹配是偶然发生的。

您使用正则表达式的修复在'^([A-Z]|Å|Ä|Ö)[a-zåäö]+$'技术上是有效的,但是组成 å、ä 和 ö 的字节实际上不允许任何其他意外的格式良好的 UTF-8 字符串意外匹配。

为了清楚起见,我建议使用'^([A-Z]|Å|Ä|Ö)([a-z]|å|ä|ö)+$'

于 2013-09-17T17:51:32.303 回答
0

经过更多的试验,我发现像这样更改正则表达式的大写部分可以解决问题:

SELECT 'Öster' REGEXP BINARY '^([A-Z]|Å|Ä|Ö)[a-zåäö]+$'

我不明白为什么这会产生不同的结果。

于 2013-09-17T15:29:05.007 回答