在MySQL中,为什么非ASCII字符真的是两个字符?

时间:2012-02-22 22:36:12

标签: mysql regex utf-8

我有一个MySQL数据库,默认编码设置为utf8。所以使用非ASCII字符应该没问题。但是,通过REGEXP命令对正则表达式来说似乎有点困难。

我正在尝试使用通配符基于正则表达式查询记录。 MySQL提供的功能对我来说已经足够了,但它们似乎有点破碎,因为非ASCII字符(我试过§和°)不匹配一个通配符而是两个。

例如,如果我搜索数据库中名为“§123”的Wiki页面,那么

SELECT * FROM wikipages WHERE title REGEXP '^.123$'

不会返回任何内容,但

SELECT * FROM wikipages WHERE title REGEXP '^..123$'

返回所需的页面(注意附加的通配符)。

对于ASCII字符,只需要一个通配符。我想这与在utf8中使用多少字节来编码字符有关。但是,我发现这种行为相当丑陋,因为如果MySQL不能平等对待所有字符,我就无法使用正则表达式。

实际上是否有充分理由说它不能被怀疑?有没有人知道如何解决我的问题?

提前致谢!

2 个答案:

答案 0 :(得分:3)

  

警告

     

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

http://dev.mysql.com/doc/refman/5.1/en/regexp.html

UTF-8是一个潜在的多字节字符集。基本上,尝试在REGEXP中对UTF-8字符进行通配符匹配有时会失败。

您可以搜索特定字符(可以自动扩展到正确的字节数),也可以使用非正则表达式模式匹配(例如LIKE),例如前缀/后缀搜索。

答案 1 :(得分:1)

您需要指明通配符的可见性

尝试

SELECT "§123" REGEXP "^.*123$" - any character 0 - n
SELECT "§123" REGEXP "^.{0,2}123$" - any character 0 - 2

两个表达式都会产生1.此外,MySQL Manual会警告多字节字符。

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