MySQL 正则表达式(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在数据库开发中,我们常常需要根据特定规则筛选或处理文本数据。例如,验证用户输入的邮箱格式、提取字符串中的电话号码,或是过滤包含敏感词的内容。这些场景都离不开 MySQL 正则表达式 的强大功能。作为关系型数据库领域的核心工具,MySQL 提供了丰富的正则表达式语法,帮助开发者高效完成复杂文本匹配任务。本文将从基础语法到高级用法,结合实际案例,带您一步步掌握这一技能。


一、什么是 MySQL 正则表达式?

正则表达式(Regular Expression,简称 regex)是一种用于匹配字符串中字符组合的模式。它通过特定的符号和规则,将复杂的文本匹配需求转化为简洁的表达式。在 MySQL 中,正则表达式主要通过 REGEXPRLIKE 关键字实现(两者功能完全相同)。

形象比喻:可以把正则表达式理解为一份“通缉令”,而数据库中的每一行数据都是被“通缉”的对象。正则表达式中的符号和规则,就相当于通缉令上的特征描述(如身高、发型等),用来精准定位符合要求的数据。


二、MySQL 正则表达式基础语法

1. 基本匹配规则

在 MySQL 中,使用 REGEXP 进行匹配时,表达式可以包含普通字符和元字符。以下是一些核心规则:

符号含义示例
.匹配任意单个字符'a.c' REGEXP 'abc' → 匹配成功
^匹配字符串开头'^a' REGEXP 'apple' → 匹配成功
$匹配字符串结尾'le$' REGEXP 'apple' → 匹配成功
|或逻辑,匹配左右任意一方'cat|dog' REGEXP 'dog' → 匹配成功

案例演示

-- 查找以 "a" 开头且以 "e" 结尾的字符串  
SELECT * FROM users WHERE name REGEXP '^a.e$';  
-- 可匹配 "ape"、"ace" 等  

2. 量词:控制匹配次数

量词允许指定某个字符或模式需要出现的次数,常见的包括:

符号含义示例
*匹配前一个字符 0 次或多次'a*b' REGEXP 'aab' → 匹配成功
+匹配前一个字符 1 次或多次'a+b' REGEXP 'aab' → 匹配成功
?匹配前一个字符 0 次或 1 次'a?b' REGEXP 'ab' → 匹配成功
{n}匹配前一个字符恰好 n 次'a{2}b' REGEXP 'aabb' → 匹配失败(需 "aab")

进阶技巧
若需匹配中文字符,可使用 [一-龥] 区间表达式。例如,^[一-龥]{2,4}$ 可匹配 2 到 4 个汉字组成的字符串。


三、字符集与特殊符号

1. 字符集:定义可匹配的字符范围

使用 [] 定义字符集,允许匹配其中任意一个字符。例如:

  • [abc]:匹配 a、b 或 c
  • [a-z]:匹配任意小写字母
  • [^0-9]:匹配非数字字符(^[] 内表示“非”)

案例

-- 查找包含数字的邮箱地址  
SELECT * FROM contacts WHERE email REGEXP '[0-9]';  

2. 转义符号 \

当需要匹配元字符本身时,需用反斜杠 \ 转义。例如:

-- 查找包含 "www." 的 URL  
SELECT * FROM links WHERE url REGEXP 'www\.';  

四、正则表达式进阶用法

1. 分组与捕获

使用 () 对模式进行分组,可实现复杂逻辑或提取子字符串。例如:

-- 匹配 "apple" 或 "app" 后接任意字符  
SELECT * FROM logs WHERE message REGEXP 'app(le)?';  

2. 反向引用

在分组的基础上,反向引用(如 \1)可引用前面匹配的内容。例如:

-- 匹配重复的单词(如 "test test")  
SELECT * FROM articles WHERE content REGEXP '(\\w+) \\1';  

3. 案例:验证邮箱格式

一个简单的邮箱正则表达式可写为:

'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}'  

解释

  • [A-Za-z0-9._%+-]+:匹配邮箱前缀(允许字母、数字及特殊符号)
  • @:必须包含 @ 符号
  • [A-Za-z0-9.-]+:匹配域名部分
  • \\.[A-Z|a-z]{2,}:匹配顶级域名(如 .com、.cn)

五、性能优化与注意事项

1. 避免全表扫描

正则表达式在 MySQL 中通常会导致全表扫描,影响查询性能。若需高频使用,建议:

  • 将关键字段建立索引(但正则表达式本身无法直接利用索引)
  • 将复杂条件拆分为多个 AND/OR 子句

2. 注意大小写敏感性

默认情况下,MySQL 的正则表达式是大小写敏感的。若需忽略大小写,可添加 i 标志:

SELECT * FROM products WHERE name REGEXP 'iphone' i;  

六、实战案例分析

案例 1:提取电话号码

假设用户输入的电话号码格式不统一,需统一提取中国大陆手机号(11 位,以 13/15/18 开头):

SELECT  
    phone,  
    SUBSTRING(phone, REGEXP_SUBSTR(phone, '1[358][0-9]{9}')) AS valid_phone  
FROM customer_info  
WHERE phone REGEXP '^1[358][0-9]{9}$';  

案例 2:过滤敏感词

创建敏感词表 sensitive_words,通过 REGEXP 实现内容过滤:

SELECT * FROM articles  
WHERE content NOT REGEXP (SELECT GROUP_CONCAT(word SEPARATOR '|') FROM sensitive_words);  

结论

通过本文,我们系统学习了 MySQL 正则表达式 的核心语法、进阶技巧及实际应用场景。掌握正则表达式不仅能提升文本处理效率,还能显著增强代码的灵活性。对于开发者而言,建议在日常工作中多尝试用正则表达式替代繁琐的字符串操作,并结合性能优化策略,让数据库查询更高效、更智能。

记住,正则表达式就像一把双刃剑:它能精准定位目标,但也可能因复杂度导致维护困难。因此,建议遵循“简洁优先”的原则,逐步构建表达式,并通过工具(如 Regex101 )实时测试效果。希望本文能成为您数据库开发路上的一份实用指南!

最新发布