SQL大师之路 09 模式匹配(正则表达式)

在处理数据库查询时,我们经常会遇到一些精准、复杂且灵活 的匹配场景:"如何校验客户录入的邮箱或手机号格式是否正确?"或 "如何筛选出名字以字母开头、中间包含特殊符号的用户名?"。面对这样的需求,传统的 LIKE 运算符配合 %_ 通配符显得束手无策,而正则表达式(Regular Expression)就是你的终极武器。


文章目录

    • [一、 正则表达式基础](#一、 正则表达式基础)
      • [1.1 基础语法](#1.1 基础语法)
    • [二、 基础语法示例](#二、 基础语法示例)
      • [2.1 基础匹配](#2.1 基础匹配)
      • [2.2 逻辑"或"匹配:管道符(|)](#2.2 逻辑“或”匹配:管道符(|))
      • [2.2 字符集匹配:方括号([])](#2.2 字符集匹配:方括号([]))
      • [2.3 范围匹配:连字符(-)](#2.3 范围匹配:连字符(-))
      • [2.4 锚点:^ and ](#2.4 锚点:^ and )
    • [三、 高阶匹配规则](#三、 高阶匹配规则)
      • [3.1 特殊字符的转义(\)](#3.1 特殊字符的转义(\))
      • [3.2 预定义字符类](#3.2 预定义字符类)
      • [3.3 重复匹配(限定符)](#3.3 重复匹配(限定符))
    • [四、 注意事项](#四、 注意事项)

一、 正则表达式基础

正则表达式是用于匹配文本的特殊字符串模式,如果说 通配符 是"模糊搜索",那么 正则表达式 就是"结构化匹配"。

1.1 基础语法

在 MySQL 中,正则表达式使用 LIKE 的语句非常相似,只是将关键字 LIKE 替换为了 REGEXP(或RLIKE,这两个是同义词):

sql 复制代码
WHERE column_name REGEXP 'pattern'
或
WHERE column_name RLIKE 'pattern'

regexp 关键字告诉MySQL,后面的字符串是一个"正则表达式",要按这个模式匹配。


二、 基础语法示例

我们这里用MySQL的示例数据库Sakila作演示。

2.1 基础匹配

最基础的匹配就是直接跟一个字符串,这会返回所有包含此字符串的结果:

示例: 查找title包含"ACADEMY"的记录。

sql 复制代码
SELECT title FROM film 
WHERE title REGEXP 'ACADEMY';

这里的效果和 LIKE '%ACADEMY%'是一样的,但是正则表达式不需要通配符。

2.2 逻辑"或"匹配:管道符(|)

如果你想同时搜索多个可能的关键词,可以使用 |

示例: 查找标题中包含 "ACADEMY" 或 "DINOSAUR" 的电影。

sql 复制代码
SELECT title FROM film 
WHERE title REGEXP 'ACADEMY|DINOSAUR';

2.2 字符集匹配:方括号([])

[] 匹配集合中的任意单个字符

示例: 查找电影标题中包含 "ABA"或 "ABE" 的记录。

sql 复制代码
SELECT title FROM film WHERE title REGEXP 'AB[AE]';
  • 反向匹配[^ABC] 表示匹配不在集合中的任意字符。

2.3 范围匹配:连字符(-)

当[]中包含很多值,并且形成一个范围时,为了简化书写,可以使用连字符定义范围。例如[0123456789]表示匹配任意数字,可以简写为[0-9],同理,[a-z]:匹配任意小写字母。

示例: 查找时长在110~119分钟的电影。

sql 复制代码
SELECT title, length FROM film 
WHERE length REGEXP '11[0-9]';

2.4 锚点:^ and $

正则表达式的^$分别代表匹配开头和匹配结尾:

示例: '^BA'表示仅匹配以BA开头的电影:

sql 复制代码
SELECT title FROM film 
WHERE title REGEXP '^BA';

示例: 'TED$'表示仅匹配以TED结尾的电影:

sql 复制代码
SELECT title FROM film 
WHERE title REGEXP 'TED$';

精确匹配: 如果在字符串的开头和结尾分别加上^$,则代表精确匹配:

示例: '^IRON MOON$' 表示精确匹配电影名为"IRON MOON"的电影

sql 复制代码
SELECT title FROM film 
WHERE title REGEXP '^IRON MOON$';

三、 高阶匹配规则

3.1 特殊字符的转义(\)

在正则表达式中,.-[ 等字符有特殊含义。如果你想匹配这些字符本身,必须进行转义。MySQL 中需要使用双反斜杠 \\进行转移。

  • 示例:查询电影rating包含'-'的记录
sql 复制代码
SELECT title, rating FROM film 
WHERE rating REGEXP '\\-';

3.2 预定义字符类

MySQL 预置了一些字符类,让 SQL 语句更具可读性,其等价写法如下:

字符类 含义 等价写法
[:digit:] 任意数字 [0-9]
[:alpha:] 任意字母 [a-zA-Z]
[:alnum:] 任意字母数字 [0-9a-zA-Z]
[:space:] 任意空白字符 空格/制表符等

3.3 重复匹配(限定符)

限定符用于控制前一个字符出现的次数:

限定符 含义 示例 匹配结果
* 0次或多次 a* (空), a, aa, aaa
+ 1次或多次 a+ a, aa, aaa
? 0次或1次 a? (空), a
{n} 恰好 n 次 [0-9]{3} 123, 456 (连续三位数字)
  • 示例:查询以3位数字开头,后面接1个空格的地址:
sql 复制代码
SELECT address FROM address
where address REGEXP '^[:digit:]{3} ';

四、 注意事项

正则表达式是 MySQL 工具箱中的"瑞士军刀",但它也有代价,请记住以下原则:

  • 优先使用 LIKE :简单的匹配不要使用正则表达式,LIKE 的性能在简单场景下远高于 REGEXP
  • 避免在开头匹配:类似于通配符,如果正则表达式以模糊匹配开头,通常无法利用索引。
  • 大小写敏感 :MySQL 默认不区分大小写。如果需要区分,请使用 REGEXP BINARY
    • 例如 WHERE title REGEXP BINARY 'apple'(仅匹配小写)。
相关推荐
李昊哲小课14 分钟前
Python办公自动化教程 - 第7章 综合实战案例 - 企业销售管理系统
开发语言·python·数据分析·excel·数据可视化·openpyxl
南汐以墨20 分钟前
一个另类的数据库-Redis
数据库·redis·缓存
RInk7oBjo44 分钟前
spring-事务管理
数据库·sql·spring
希望永不加班1 小时前
SpringBoot 数据库连接池配置(HikariCP)最佳实践
java·数据库·spring boot·后端·spring
李昊哲小课1 小时前
Python办公自动化教程 - 第5章 图表创建 - 让数据可视化
python·信息可视化·数据分析·数据可视化·openpyxl
黑牛儿1 小时前
MySQL 索引实战详解:从创建到优化,彻底解决查询慢问题
服务器·数据库·后端·mysql
捧月华如1 小时前
RAG 入门-向量存储与企业级向量数据库 milvus
数据库·milvus
杨云龙UP2 小时前
Oracle Data Pump实战:expdp/impdp常用参数与导入导出命令整理_20260406
linux·运维·服务器·数据库·oracle
想唱rap2 小时前
线程池以及读写问题
服务器·数据库·c++·mysql·ubuntu
爱丽_3 小时前
B+ 树范围查询为什么快:页分裂/合并、索引设计与 SQL 写法优化
数据库·算法·哈希算法