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.) 配合正则使用,代码更清晰。
相关推荐
Dxy12393102162 小时前
正则表达式如何匹配提取文章日期
数据库·mysql·正则表达式
元宝骑士2 小时前
MySQL联表查询优化实战:小表驱动大表的联合索引设计
后端·mysql
小陈工2 小时前
Python Web开发入门(十六):前后端分离架构设计——从“各自为政”到“高效协同”
开发语言·前端·数据库·人工智能·python
APguantou2 小时前
NCRE-三级数据库技术-第13章-大规模数据库架构
数据库·数据库架构
前进的李工2 小时前
MySQL用户管理与权限控制指南(含底层架构说明)
开发语言·数据库·sql·mysql·架构
刘~浪地球2 小时前
Redis 从入门到精通(十一):持久化配置
数据库·redis·缓存
正在走向自律3 小时前
深度剖析 KES 行标识体系:OID 与 ROWID 核心原理、实战案例及性能优化
数据库·oid·kes·rowid
一直都在5723 小时前
MySQL索引优化
android·数据库·mysql
wjp@0013 小时前
SQL server导出导入数据
运维·服务器·数据库