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 工具。
