mysql 8.0+ 使用 regexp_like 需版本≥8.0.4且启用icu正则引擎,不支持pcre语法如(?i),应改用第四个参数如'i'(忽略大小写)、'm'(多行模式)等。

MySQL 8.0 里 REGEXP_LIKE 怎么写才不报错
MySQL 5.7 及更早版本压根不支持 REGEXP_LIKE,直接用会报 FUNCTION REGEXP_LIKE does not exist。必须确认版本 ≥ 8.0.4,且默认启用正则引擎(一般没问题,但某些云厂商定制版可能关了)。
常见错误是把 PCRE 风格的写法直接搬过去,比如 d+ 或 (?i)abc —— MySQL 用的是 ICU 正则库,不支持 ?i 这类内联标志,得改用第四个参数:REGEXP_LIKE(col, 'abc', 'i')。
-
'i':忽略大小写;'c':区分大小写(默认);'m':多行模式(^/$匹配每行首尾) - 锚点
^和$默认只匹配整个字符串首尾,加'm'才能匹配换行符两侧 - 不支持
Q...E转义字面量,想匹配含正则元字符的字符串,得手动对.、*、[等加反斜杠
PostgreSQL 的 ~ 和 ~* 到底怎么选
~ 是区分大小写的正则匹配操作符,~* 是忽略大小写的。别用 ILIKE 替代——它只支持简单通配(%/_),不支持正则。
性能上,~ 比 ~* 快一截,尤其在有索引时。如果字段建了 text_pattern_ops 或 pg_trgm 索引,~ 能走索引,~* 大概率全表扫(除非你显式用 LOWER(col) ~ 'pattern' 并给 LOWER(col) 建函数索引)。
- 要查邮箱本地部分是否含数字:
email ~ '^[a-zA-Z]+[0-9]'::text - 想避免大小写陷阱又想索引友好:
LOWER(email) ~ '^admin'+CREATE INDEX ON users (LOWER(email)) - 别写
email ~* '^ADMIN'——看似省事,实际放弃索引加速机会
SQLite 用 REGEXP 前必须干的三件事
SQLite 原生不带正则函数,REGEXP 是个占位符,必须靠外部扩展或自定义函数注入。直接执行 SELECT * FROM t WHERE x REGEXP 'foo' 会报 no such function: REGEXP。
1 系统使用三层构架2 数据库访问使用sqlHelper3 编辑器使用FreeTextBox4 布局采用Div+Css5 正则表达式实现数据验证6 动态构建sql查询语句
常见做法是加载 libsqlite3-mod-regexp(Linux)或编译时加 -DSQLITE_ENABLE_REGEXP,但更可控的方式是用应用层注册函数。比如 Python 的 sqlite3 模块:conn.create_function('REGEXP', 2, lambda pattern, text: re.search(pattern, text) is not None)。
- 自定义函数返回值必须是整数:0 表示不匹配,非 0 表示匹配(别返回
True/False) - 正则引擎是 Python 的
re,不是 SQLite 内置的,所以支持re.DOTALL等标志,但要注意跨平台兼容性 - 如果用的是 SQLCipher 或某些嵌入式环境,
REGEXP几乎肯定不可用,得改用GLOB或LIKE将就
正则提取字段时,substring() 和 regexp_replace() 别混用
想从字符串里抠出手机号,用 substring(col FROM 'd{11}')(PostgreSQL)或 REGEXP_SUBSTR(col, '\d{11}') (MySQL 8.0+);想删掉括号和空格,才用 regexp_replace()。混用会导致逻辑错乱,比如误把“匹配成功”当“提取结果”。
MySQL 的 REGEXP_SUBSTR 第二个参数是正则,第三个是位置(默认 1),第四个是出现序号(默认 1),第五个是匹配参数(如 'c')。漏掉第四个参数想取第二个匹配项?结果永远是第一个。
- PostgreSQL 提取第二个括号内容:
substring(col FROM '(([^)]+))' FOR 2)(注意FOR 2指子组编号) - MySQL 提取所有邮箱并拼成逗号串:
REGEXP_REPLACE(col, '([^@]+@[^@]+\.[^@]+)', '$1', 1, 0, 'g')—— 这里'g'很关键,否则只换第一个 - SQLite 没
REGEXP_SUBSTR,只能靠自定义函数或先REGEXP判断再用SUBSTR+INSTR硬拆
最常被忽略的是:正则提取函数在 NULL 输入时大多返回 NULL,但有些数据库(如旧版 MySQL)会返回空字符串,导致后续 LENGTH() 或拼接出错。检查前先 WHERE col IS NOT NULL 更稳妥。









