You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何MariaDB 10.2中RLIKE会匹配4字节表情符号?

问题解析:MariaDB 10.2正则^[?]+$匹配4字节表情符号的原因及解决办法

问题现象

执行以下SQL时,本应仅匹配问号字符的正则表达式^[?]+$,却匹配了4字节表情符号😃,返回结果为1(匹配成功):

(root@127.0.0.1:3306) [test]> select '😃' RLIKE '^[?]+$';
+-----------------------------------+
| '\xF0\x9F\x98\x83' RLIKE '^[?]+$' |
+-----------------------------------+
|                                 1 |
+-----------------------------------+
1 row in set (0,00 sec)

当前数据库排序规则均为utf8mb4_general_ci:

(root@127.0.0.1:3306) [test]> SHOW VARIABLES LIKE 'collation%';
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | utf8mb4_general_ci |
| collation_database   | utf8mb4_general_ci |
| collation_server     | utf8mb4_general_ci |
+----------------------+--------------------+
3 rows in set (0,00 sec)

原因

MariaDB中RLIKE/REGEXP的匹配行为会受当前字符集排序规则的影响:

  • utf8mb4_general_ci是通用排序规则,它的字符等价映射逻辑比较宽松,会将部分Unicode字符(包括你测试的这个4字节表情符号)与问号?视为“等价字符”,导致正则字符类[?]会匹配到这些被归为等价的字符。
  • 这种等价匹配是排序规则的设计特性,目的是简化某些场景下的字符比较,但在正则精确匹配时会带来意外结果。

解决办法

1. 使用二进制匹配(临时方案)

在正则表达式前添加BINARY修饰符,强制按字符的原始字节值进行精确匹配,忽略排序规则的等价映射:

select '😃' RLIKE BINARY '^[?]+$';

执行后会返回0,即不匹配表情符号,仅匹配问号。

2. 更换更严格的排序规则(长期方案)

将数据库/表/列的排序规则更换为utf8mb4_unicode_ci或更现代的规则(如MariaDB 10.3+支持的utf8mb4_unicode_520_ci),这类排序规则的字符等价映射更符合Unicode标准,不会将表情符号与问号归为一类。

修改数据库排序规则的示例:

ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

注意:修改排序规则可能影响已有数据的查询结果,建议先做测试再批量修改。

3. 改用REGEXP_LIKE函数(若版本支持)

MariaDB 10.0.5及以上支持REGEXP_LIKE函数,可通过指定c(大小写敏感,且按字符精确匹配)修饰符实现精确匹配:

SELECT REGEXP_LIKE('😃', '^[?]+$', 'c');

该语句同样会返回0,实现预期的精确匹配效果。

内容的提问来源于stack exchange,提问作者Ela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:10:55