MySQL REGEXP语句异常:为何"»"匹配`^[-а-я]*$`返回1?
为什么
SELECT "»" REGEXP "^[-а-я]*$"返回1? 核心原因
问题出在MySQL正则表达式的字符范围匹配逻辑上——它依赖于当前连接的字符集排序规则,而非字符的原始编码或字节值:
- 正则里的
[-а-я]定义了从连字符-到西里尔字母я的匹配范围。在默认排序规则(比如utf8_general_ci、utf8mb4_general_ci)中,字符匹配按排序权重归类,而非编码值。 »(Unicode U+00BB)的排序权重恰好落在-到я的范围内,所以被判定为匹配;而«(U+00AB)的权重不在这个区间,因此不匹配。- 加
BINARY也没用的原因:REGEXP BINARY按字节序列匹配,»的UTF-8字节是0xC2 0xBB,连字符是0x2D,я的UTF-8字节是0xD1 0x8F,前者的字节范围依然在后者之间,所以还是会被匹配。
解决办法
要精准匹配仅含连字符和西里尔字母а-я的字符串,换两种写法就行:
- MySQL 8.0+用Unicode属性匹配(最可靠)
这条只认连字符和西里尔字母,SELECT "»" REGEXP '^[-\\p{Cyrillic}]*$';»会返回0。 - MySQL 5.x用精确编码范围
直接指定西里尔字母а-я的Unicode编码区间:
这样就能排除SELECT "»" REGEXP '^[-\\x{0430}-\\x{044F}]*$';»这类非目标字符。
内容的提问来源于stack exchange,提问作者VladimirM4K
相关产品推荐
相关产品推荐

