mysql 8.0 的 regexp_like 变强并非因默认启用 icu 库,而是函数化、参数化和上下文化升级;其底层仍默认使用 posix ere 引擎,icu 需编译显式开启且生产极少启用。

REGEXP_LIKE 函数本身不带来“更多模式”,真正支持更多匹配能力的是 MySQL 8.0 默认启用的 **ICU 库编译选项**——但注意:这不是默认行为,而是可选配置;实际生产环境绝大多数仍用原生引擎。所谓“更强”,主要来自函数接口升级与语义标准化,不是底层正则引擎替换。
MySQL 8.0 的 REGEXP_LIKE 不是靠 ICU 才变强的
官方文档和源码验证都明确:MySQL 8.0 默认仍使用 Henry Spencer 的 POSIX ERE 实现(和 5.7 一致),ICU 支持需在编译时显式开启(-DWITH_ICU=system 或 builtin),且生产部署极少启用。你执行 SELECT VERSION(), @@version_compile_os; 并查构建参数,基本看不到 ICU 相关痕迹。
所以别被“ICU 集成”误导——真正让正则“好用”的,是函数化、参数化、上下文化:
-
REGEXP_LIKE可嵌入SELECT、CASE、生成列、CHECK约束,而 5.7 的REGEXP只能在WHERE里当布尔运算符用 -
match_type参数(如'i'、'm')让大小写、多行模式控制变得显式可控,5.7 完全依赖collation或包裹LOWER() -
REGEXP_SUBSTR、REGEXP_REPLACE、REGEXP_INSTR这些函数在 5.7 根本不存在,属于 8.0 新增能力
MySQL 5.7 的 REGEXP 为什么看起来“弱”?
它不是引擎差,而是定位窄、语义模糊:
- 对
NULL输入返回NULL,导致WHERE col REGEXP 'x'在col IS NULL时既不进也不报错,逻辑难推理 - 行为受
sql_mode影响(比如NO_BACKSLASH_ESCAPES会让\d解析失败),而 8.0 的REGEXP_LIKE行为更稳定 - 不支持 Perl 风格简写(
d、w、s),但这是 POSIX ERE 规范限制,8.0 原生引擎也一样不支持——得写成[0-9]、[a-zA-Z0-9_]、[[:space:]]
想真用上 ICU 的高级模式?先确认是否启用
ICU 引擎才支持 Unicode 属性类(如 p{L})、Unicode 大小写折叠、更严格的 Unicode 字符类等。但必须满足:
- MySQL 编译时启用了 ICU(查
SHOW VARIABLES LIKE 'version_compile_machine';和构建日志) - 运行时未禁用(
SET GLOBAL regexp_engine = 'icu';,但该变量在多数发行版中不可设) - 即便启用,
REGEXP_LIKE默认仍走原生引擎;目前无语法强制切换到 ICU 模式
换句话说:你写的 REGEXP_LIKE(email, 'p{L}+', 'u') 在标准 MySQL 8.0 发行版里会直接报错,不是功能没开放,而是根本没连上 ICU。
真正影响匹配能力的,是写法是否利于优化器
很多人以为换函数就能提升性能或覆盖更多场景,其实关键在表达方式:
-
REGEXP_LIKE(col, '^A.*[0-9]$')和col REGEXP '^A.*[0-9]$'执行计划几乎一样,都不走索引 - 但你可以用生成列 + 索引把固定模式固化下来:
ADD COLUMN is_phone TINYINT AS (REGEXP_LIKE(phone, '^1[3-9]\d{9}$')) STORED,再建索引 - 而 5.7 连这一步都做不到——没有生成列支持正则,也没
REGEXP_LIKE函数
复杂点在于:函数能力 ≠ 引擎能力,兼容性陷阱藏在 NULL 处理、match_type 默认值、以及你以为开启了 ICU 其实没开这些地方。











