MySQL的REGEXP和RLIKE本质相同,仅支持POSIX ERE子集,不支持捕获组等高级特性;8.0+推荐用REGEXP_LIKE()函数,性能无差异但更可控,正则查询通常无法走索引。

MySQL 的 REGEXP 和 RLIKE 本质一样
MySQL 不支持 PCRE 或 .NET 风格的正则,只提供 POSIX ERE(扩展正则)子集,且不支持捕获组、反向引用、懒惰匹配等高级特性。所有正则操作都通过 REGEXP(或同义词 RLIKE)操作符完成,返回 1(匹配)、0(不匹配)或 NULL(任一操作数为 NULL)。
注意:MySQL 8.0+ 引入了 REGEXP_LIKE() 函数,语义更清晰,推荐新项目优先使用;但老版本只能用操作符。
常见写法与容易踩的坑
直接在 WHERE 中使用 REGEXP 最常见,但几个细节极易出错:
-
REGEXP默认**不区分大小写**(受列字符集和校对规则影响),想严格区分需显式指定BINARY或使用COLLATE utf8mb4_bin - 字符串中的反斜杠
\在 SQL 字符串里要写成\\,比如匹配数字要写'[0-9]',而匹配字面量反斜杠得写'\\\\' -
^和$锚点作用于**整行**,不是单个字段值的“开头/结尾”——如果字段含换行符,^可能匹配中间某行开头 - 空字符串
''能匹配任意非NULL字段(因为 ERE 中空模式恒真),务必避免漏判
SELECT * FROM users WHERE name REGEXP '^[A-Z][a-z]+ [A-Z][a-z]+$'; -- 匹配“名 姓”格式(首字母大写) SELECT * FROM logs WHERE content REGEXP BINARY 'ERROR|FATAL'; -- 强制区分大小写
MySQL 8.0+ 的 REGEXP_LIKE() 更可控
这个函数把模式、匹配选项拆成参数,比操作符更明确,也支持 ic(忽略大小写)、c(区分大小写)、m(多行模式)等标志:
- 第三个参数是可选的标志字符串,如
'c'表示区分大小写,'m'让^/$匹配每行首尾 - 不加标志时默认行为与
REGEXP操作符一致(即隐含'i') - 性能上无本质差异,但逻辑更易读、调试更方便
SELECT * FROM products
WHERE REGEXP_LIKE(sku, '^[A-Z]{2}\\d{6}$', 'c'); -- 严格区分大小写,匹配如 AB123456性能和替代建议
正则查询无法使用普通 B+Tree 索引加速,全表扫描是常态。除非数据量极小或已用覆盖索引预过滤,否则应谨慎上线。
- 能用
=、LIKE 'prefix%'或全文索引(MATCH ... AGAINST)解决的,别硬上正则 - 若需高频正则匹配,考虑在应用层做(如 Python 的
re.search),或把提取结果存为额外字段并建索引 - MySQL 8.0+ 支持生成列(
GENERATED COLUMN),可把正则提取的关键信息(如邮箱域名、手机号区号)固化并索引
真正复杂的文本分析,MySQL 正则能力太弱,该交给 Elasticsearch 或专用 NLP 工具。

