当我在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'也不匹配。
我该怎么办?
答案 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åäö]+$'
我不明白为什么会产生不同的结果。