mysql 8.0+中匹配字面下划线应使用regexp 'user_name'(双反斜杠转义)或regexp 'user[_]name'(字符类避免转义),因下划线在正则中无特殊含义,无需像like中那样escape;整行匹配需加^和$锚点。

MySQL 8.0+ 中用 REGEXP 匹配带下划线的模式字符串
MySQL 5.7 及更早版本不支持完整正则匹配,REGEXP(或别名 RLIKE)在 8.0+ 才真正支持 POSIX ERE,且默认区分大小写。如果你要查类似 user_name、order_id 这种含下划线的字段值,不能直接用 LIKE '%_%'——它会匹配任意单字符,而非字面意义的下划线。
正确做法是转义下划线或使用字符类:
-
WHERE column_name REGEXP 'user\_name':双反斜杠是 MySQL 字符串字面量要求(第一个反斜杠转义第二个,最终传给正则引擎的是_) -
WHERE column_name REGEXP 'user[_]name':把下划线包进方括号,避免转义麻烦,也更易读 - 注意:MySQL 正则默认是“部分匹配”,即
'abc' REGEXP 'b'返回 true;如需整行匹配,加锚点^和$,例如^user[_]name$
PostgreSQL 中用 ~ 操作符处理下划线和特殊字符
PostgreSQL 的正则语法更贴近标准,下划线在正则中本就无特殊含义(不像 . 或 *),所以不需要转义。但要注意:它的 ~ 是区分大小写的,~* 才不区分。
常见误操作是混淆 LIKE 和正则行为:
-
WHERE column_name ~ 'user_name'→ 正确,下划线就是字面量 -
WHERE column_name LIKE 'user_name'→ 错误,这里_是通配符,会匹配任意单字符 - 若想在正则中匹配实际的下划线 + 其他元字符(比如
user_name.*.log),只对.、*、^等转义,_保持原样
SQL Server 不支持原生正则,得靠 PATINDEX 或 CLR
SQL Server 2017+ 仍无内置正则函数,LIKE 是主力,但它无法表达“至少两个下划线”或“下划线后跟数字”这类逻辑。这时候 PATINDEX('%pattern%', column) 是更灵活的替代:
-
PATINDEX('%[_]%', column_name) > 0:查含下划线的记录([_]把下划线当字面量,避免被当作通配符) -
PATINDEX('%[_][0-9]%', column_name) > 0:查下划线后紧跟数字的字符串 - 注意:PATINDEX 返回位置索引,不是布尔值,所以必须显式判断是否大于 0
- 真需要复杂正则?只能启用 CLR 集成并部署自定义函数,生产环境需额外审批和维护成本
跨数据库可移植方案:优先用 LIKE + 字符串函数兜底
如果查询要跑在多个数据库上(比如开发用 SQLite,测试用 PostgreSQL,上线用 MySQL),硬写正则会立刻失效。这时应退回到最保守但通用的方式:
- 查“含下划线”:
WHERE column_name LIKE '%|_%' ESCAPE '|'(用ESCAPE定义转义符,确保下划线被当字面量) - 查“以下划线开头”:
WHERE SUBSTRING(column_name, 1, 1) = '_'(SUBSTRING在主流数据库中语义一致) - 避免依赖正则的模糊边界场景,比如“匹配单词边界”——不同数据库对
支持度差异极大,SQLite 根本不认
正则在 SQL 里从来不是银弹。下划线看着简单,但一牵扯转义规则、引擎版本、大小写策略,就很容易查出意外结果。动手前先 SELECT VERSION() 或查文档确认当前环境支持哪一级正则语法,比硬套示例代码更省时间。











