Mysql 07: 正则表达式查询(REGEXP)全解

MySQL 正则表达式查询(REGEXP)全解

在 MySQL 中,正则表达式查询 通过 REGEXP 关键字实现,相比普通的 LIKE 模糊查询,它支持更强大的模式匹配(如开头 / 结尾、重复次数、范围匹配等)。

本文围绕图片中的 8 大核心场景,从基础到进阶,用极简代码 + 场景说明,带你彻底掌握 MySQL 正则查询。


一、核心语法与关键字

1. 基本语法

sql 复制代码
SELECT 字段 FROM 表 WHERE 字段 REGEXP '正则表达式';
  • REGEXP :核心关键字,返回 1(匹配成功)或 0(匹配失败)
  • NOT REGEXP:反向匹配,查询不满足条件的结果
  • 语法规则:遵循 MySQL 正则语法(与 PCRE 类似,但有少量差异)

2. 图片核心知识点对应

图片序号 正则关键字 功能
(1) ^ 匹配以特定字符 / 字符串开头
(2) $ 匹配以特定字符 / 字符串结尾
(3) . 匹配任意单个字符(包括空格)
(4) * / + 匹配多个字符* 表示 0 个及以上,+ 表示 1 个及以上
(5) 字符串 直接匹配指定字符串存在
(6) [] 匹配指定字符集合中的任意一个
(7) [^] 匹配不在指定集合中的字符
(8) {n} / {n,m} 指定字符出现的次数范围

二、准备测试数据

创建一张学生表 student,用于所有示例:

sql 复制代码
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    email VARCHAR(30) NOT NULL,
    phone VARCHAR(20) NOT NULL
);

INSERT INTO student (name, email, phone) VALUES
('张三', 'zhangsan@test.com', '13812345678'),
('李四', 'lisi@163.com', '13987654321'),
('王五', 'wangwu@qq.com', '15000001111'),
('赵六', 'zhaoliu@abc.com.cn', '18622223333'),
('孙七', 'sunqi@test.com', '17799998888');

三、核心场景详解 + 代码示例

1. (1) 查询以特定字符开头(^

核心逻辑

^ 表示匹配行的开头,即字段值必须以该字符 / 字符串开始。

代码示例
sql 复制代码
-- 查询姓名以'张'开头的学生
SELECT * FROM student WHERE name REGEXP '^张';

-- 查询邮箱以'zh'开头的学生
SELECT * FROM student WHERE email REGEXP '^zh';
结果说明
  • ^张:只匹配姓名第一个字是 "张" 的记录(张三)。
  • ^zh:只匹配邮箱第一个字符是 "zh" 的记录(zhangsan@test.com)。

2. (2) 查询以特定字符结尾($

核心逻辑

$ 表示匹配行的结尾,即字段值必须以该字符 / 字符串结束。

代码示例
sql 复制代码
-- 查询邮箱以'com'结尾的学生
SELECT * FROM student WHERE email REGEXP 'com$';

-- 查询姓名以'六'结尾的学生
SELECT * FROM student WHERE name REGEXP '六$';
结果说明
  • com$:匹配邮箱最后三个字符是 "com" 的记录(李四、王五、赵六)。
  • 六$:匹配姓名最后一个字是 "六" 的记录(赵六)。

3. 匹配任意单个字符(.

核心逻辑

. 是通配符,匹配任意一个字符 (包括空格),注意与 LIKE_ 区分。

代码示例
sql 复制代码
-- 查询姓名为"张_"的学生(张后面跟任意一个字)
SELECT * FROM student WHERE name REGEXP '张.';

-- 查询邮箱包含'@...com'(@和com之间有任意字符)
SELECT * FROM student WHERE email REGEXP '@.com';
结果说明
  • 张.:匹配姓名长度为 2,且第一个字是 "张" 的记录(张三)。
  • @.com:匹配 @com 之间有且仅有一个字符的邮箱(如 @1.com@q.com)。

4. 匹配多个字符(*+

核心逻辑
  • * :匹配前面的字符 0 次或多次
  • + :匹配前面的字符 1 次或多次(至少出现一次)。
代码示例
sql 复制代码
-- 查询姓名以'张'开头,后面跟任意字符(0个及以上)
SELECT * FROM student WHERE name REGEXP '张.*';

-- 查询邮箱包含'test',且前面至少有1个字符
SELECT * FROM student WHERE email REGEXP '.+test';
结果说明
  • 张.*:匹配所有以 "张" 开头的姓名(张三)。
  • .+test:匹配 "test" 前面至少有一个字符的邮箱(孙七的 sunqi@test.com)。

5. 匹配指定字符串(直接写字符串)

核心逻辑

如果正则中写普通字符串,MySQL 会判断该字段是否包含这个子串

代码示例
sql 复制代码
-- 查询姓名中包含'三'的学生
SELECT * FROM student WHERE name REGEXP '三';

-- 查询邮箱中包含'163'的学生
SELECT * FROM student WHERE email REGEXP '163';
结果说明
  • :匹配姓名中只要含有 "三" 字的记录(张三)。
  • 163:匹配邮箱中含有 "163" 子串的记录(李四)。

6. 匹配指定字符集合中的任意一个([]

核心逻辑

[字符集] 表示匹配集合中的任意一个字符

代码示例
sql 复制代码
-- 查询姓名中包含'张'或'李'的学生
SELECT * FROM student WHERE name REGEXP '[张李]';

-- 查询电话中第二位是'3'或'9'的学生
SELECT * FROM student WHERE phone REGEXP '^.(3|9)'; -- 或用 [39]
结果说明
  • [张李]:匹配姓名中含有 "张" 或 "李" 的记录(张三、李四)。
  • ^.(3|9):匹配电话第二位是 3 或 9 的记录(张三、李四)。

7. 匹配指定字符以外的字符([^]

核心逻辑

[^字符集] 表示匹配不在该集合中的任意一个字符

代码示例
sql 复制代码
-- 查询姓名中不包含'张'的学生
SELECT * FROM student WHERE name REGEXP '[^张]';

-- 查询电话中第二位不是'3'的学生
SELECT * FROM student WHERE phone REGEXP '^.[^3]';
结果说明
  • [^张]:匹配姓名中不含 "张" 字的记录(李四、王五、赵六、孙七)。
  • ^.[^3]:匹配电话第二位不是 3 的记录(王五、赵六、孙七)。

8. 指定字符出现次数({n} / {n,m}

核心逻辑
  • {n}:匹配前面的字符恰好出现 n 次
  • {n,}:至少出现 n 次。
  • {n,m}:出现次数在 n 到 m 之间。
代码示例
sql 复制代码
-- 查询姓名恰好是2个字的学生(正则:任意字符出现2次)
SELECT * FROM student WHERE name REGEXP '^.{2}$';

-- 查询电话中数字'1'连续出现至少2次的记录
SELECT * FROM student WHERE phone REGEXP '1{2,}';
结果说明
  • ^.{2}$:匹配长度为 2 的姓名(张三、李四、王五、赵六、孙七)。
  • 1{2,}:匹配电话中连续两个及以上 "1" 的记录(张三、李四、王五、赵六、孙七)。

四、综合实战:复杂正则查询

sql 复制代码
-- 需求:查询一班(假设姓名对应班级)中,邮箱以'test'开头或结尾,且分数>80的学生
-- 注:此处用name模拟班级条件
SELECT 
    s.name, 
    s.email,
    sc.score
FROM student s
JOIN score sc ON s.id = sc.stu_id
WHERE 
    (s.email REGEXP '^test' OR s.email REGEXP 'test$')
    AND sc.score > 80;

五、核心注意事项(避坑指南)

1. REGEXPLIKE 的区别

特性 LIKE REGEXP
匹配范围 仅支持简单的 %(任意)和 _(单个) 支持完整正则语法
默认规则 匹配整个字段 匹配字段的任意位置 (若要全匹配需加 ^$
性能 一般 一般(复杂正则会全表扫描)

六、核心总结

  1. 核心关键字REGEXP(匹配)、NOT REGEXP(不匹配)。
  2. 8 大核心场景
    • ^ 开头,$ 结尾。
    • . 任意单字符,* 任意多字符,+ 至少 1 个字符。
    • [] 任意一个,[^] 排除。
    • {n} 精确次数,{n,m} 范围次数。
  3. 使用场景:复杂数据筛选、报表统计、数据清洗(如手机号、邮箱格式校验)。
  4. 注意 :多表复杂查询中,别名 (s.) 配合正则使用,代码更清晰。
相关推荐
牛栓柱5 小时前
【后端实战】用 Supabase + React/TS 零成本构建高并发 Multi-Agent 服务
前端·数据库·人工智能·后端·react.js·前端框架
yuezhilangniao5 小时前
xtr备份prepare到底变化了啥
mysql
yyk的萌5 小时前
创建属于自己的mysql的mcp
mysql·adb·ai·mcp
流烟默5 小时前
腾讯云Centos7.6使用yum安装MySQL8
mysql·centos·腾讯云
仙俊红5 小时前
如何优化 MySQL 深分页 SQL
android·sql·mysql
yyuuuzz5 小时前
谷歌云基础服务的入门认知
linux·运维·服务器·数据库·人工智能·github
超梦dasgg5 小时前
工作中 MySQL 读写分离主从延迟:成因、影响、落地方案、生产实战处理
数据库·mysql
Wonderful U6 小时前
Python+Django实战:打造智能生鲜果蔬进销存管理系统(采购入库、库存预警、销售开单、毛利统计)
数据库·python·django
Demon1_Coder6 小时前
Day4-微服务-Seata默认事务
java·数据库·微服务
疯狂热爱代码的00后6 小时前
入门必看! MySQL增删改查全套示例SQL 直接复制运行
mysql