regexp 是 mysql 中处理复杂模糊搜索的高效工具,但仅适用于超越 like 线性匹配能力的场景,如数字紧邻、多前缀匹配、字符排除、重复次数控制等;rlike 与其完全等价;需注意大小写敏感、null 返回 null、索引失效及 posix ere 限制。

REGEXP 是 MySQL 中做复杂模糊搜索最直接有效的手段,比 LIKE 灵活得多,但不能盲目替换 —— 简单场景用 LIKE 更快、更稳。
什么时候该用 REGEXP 而不是 LIKE
当你需要表达的逻辑超出了“开头/结尾/包含”这种线性结构时,REGEXP 才真正派上用场:
-
LIKE 'a%b'只能匹配 “a…b”,中间任意字符;但如果你要 “a 后面紧跟着数字,再跟 b”,就得写REGEXP 'a[0-9]b' - 想匹配 “手机号以 13、15 或 18 开头”,
LIKE得写三个OR,而REGEXP '^1[358]'一行搞定 - 要排除某些字符(比如邮箱里不能含空格),
REGEXP '^[^[:space:]]+@[^[:space:]]+\.[^[:space:]]+$'是唯一可行路径 -
LIKE不支持重复次数控制,而REGEXP 'a{2,4}'明确匹配 2~4 个连续 a
REGEXP 和 RLIKE 有什么区别
没区别 —— RLIKE 就是 REGEXP 的完全同义词,MySQL 官方文档明确标注二者等价。选哪个纯看团队习惯或旧代码风格。
- 写
WHERE name REGEXP '^张'和WHERE name RLIKE '^张'效果完全一样 - 执行计划、索引使用、错误提示都一致,不存在性能或兼容性差异
- 注意:MySQL 不支持 PCRE 风格(比如
(?i)忽略大小写),只支持 POSIX ERE(扩展正则),所以别套用其他语言经验
常见踩坑点:大小写、空值和索引失效
REGEXP 默认区分大小写,且对 NULL 值返回 NULL(不是 FALSE),这常导致结果漏掉或逻辑错判:
- 想不区分大小写?加
BINARY操作符反而强制区分;正确做法是用COLLATE utf8mb4_general_ci或确保字段本身用的是不区分大小写的校对集 -
WHERE content REGEXP 'abc'对content IS NULL的行永远不匹配,也不会报错,容易遗漏数据 -
REGEXP几乎无法走索引(即使字段有索引),特别是带^或$以外的模式;REGEXP '^admin'可能用上前缀索引,但REGEXP 'admin'基本等于全表扫描 - 正则引擎在 MySQL 中较弱,不支持懒惰匹配、反向引用、命名捕获组等高级特性
实用示例:从简单到稍复杂
以下语句都经过 MySQL 8.0+ 实测,注意引号必须是单引号,且正则字符串里不要混用双引号:
- 查所有以 “张” 或 “李” 开头的姓名:
WHERE name REGEXP '^[张李]' - 查邮箱域名是 gmail.com 或 outlook.com:
WHERE email REGEXP '@(gmail|outlook)\.com$' - 查身份证号(18位,末位可能是 X):
WHERE id_card REGEXP '^[0-9]{17}[0-9Xx]$' - 查不含中文、不含空格的纯英文用户名:
WHERE username REGEXP '^[a-zA-Z0-9_]+$'
真正难的不是写对正则,而是确认它在百万级表上跑得动 —— 大多数时候,你得先用 WHERE column LIKE 'prefix%' 缩小范围,再用 REGEXP 做二次筛选。











