我怎样才能在mysql regexp中匹配大写ÅÄÖ

时间:2013-09-17 13:29:02

标签: mysql regex unicode

当我在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'也不匹配。

我该怎么办?

2 个答案:

答案 0 :(得分:2)

我意识到你已经找到了解决方案,但想解释它为什么会起作用。 MySQL中的REGEXP不适用于“字符”,而是works with bytes。 Å,Ä,Ö,å,ä和ö都是UTF-8中的双字节字符。当它们在正则表达式[ ]构造中使用时,正则表达式引擎分别查看这些字节中的每一个,并且仅尝试匹配一个字节而不是组成整个字符的两个字节。如果将这些字符分解为其组成字节,您可以看到为什么某些匹配由fluke发生。

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

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

答案 1 :(得分:0)

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

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

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