[一、REGEXP / RLIKE](#一、REGEXP / RLIKE)
[四、REGEXP vs LIKE 对比](#四、REGEXP vs LIKE 对比)
[六、PHP 脚本中使用 REGEXP](#六、PHP 脚本中使用 REGEXP)
前言
在日常数据库查询中,LIKE '%关键词%' 能满足简单的模糊匹配需求。但当需要更灵活、更精确的文本模式匹配 时,MySQL 提供了强大的 正则表达式功能。
本文将全面介绍 MySQL 中 REGEXP 和 RLIKE 的使用方法、常用模式、实战案例及注意事项,助你轻松驾驭复杂文本查询。
一、REGEXP / RLIKE
REGEXP和RLIKE是 MySQL 中用于正则表达式匹配的操作符;- 二者完全等价 ,可互换使用(
RLIKE是REGEXP的同义词); - 返回
1(TRUE)表示匹配成功,0(FALSE)表示不匹配; - 默认不区分大小写 (可通过
BINARY关键字开启区分大小写)。
基本语法
sql
SELECT columns
FROM table_name
WHERE column_name REGEXP 'pattern';
SELECT columns
FROM table_name
WHERE column_name RLIKE 'pattern';
注意:
pattern是一个字符串字面量,不是 SQL 表达式。
二、常用正则表达式模式速查表
| 模式 | 说明 | 示例 |
|---|---|---|
^ |
匹配字符串开头 | ^st → 匹配 "start" |
$ |
匹配字符串结尾 | ok$ → 匹配 "book" |
. |
匹配任意单个字符(除换行符) | a.c → 匹配 "abc", "a2c" |
[abc] |
匹配 a、b 或 c 中任意一个 | [aeiou] → 匹配元音字母 |
[^abc] |
匹配 非 a、b、c 的任意字符 | [^0-9] → 匹配非数字 |
[a-z] |
匹配任意小写字母 | [A-Z] → 大写字母 |
[0-9] |
匹配任意数字 | 等价于 \d(但 MySQL 不支持 \d) |
| `p1 | p2` | 匹配 p1 或 p2 |
* |
前面元素出现 0 次或多次 | zo* → "z", "zo", "zoo" |
+ |
前面元素出现 1 次或多次 | zo+ → "zo", "zoo"(不含 "z") |
? |
前面元素出现 0 次或 1 次 | colou?r → "color" 或 "colour" |
{n} |
精确匹配 n 次 | o{2} → "food" 中的 "oo" |
{n,m} |
匹配 n 到 m 次 | a{2,4} → "aa", "aaa", "aaaa" |
注意 :在 SQL 字符串中,反斜杠
\需要转义为\\。
三、实战案例解析
1. 匹配开头或结尾
sql
-- 查找以 "St" 开头的名字(不区分大小写)
SELECT name FROM users WHERE name REGEXP '^st';
-- 查找以 "ing" 结尾的单词
SELECT word FROM dictionary WHERE word REGEXP 'ing$';
2. 包含特定子串
sql
-- 查找包含 "admin" 的用户名
SELECT username FROM accounts WHERE username REGEXP 'admin';
3. 匹配字符集合
sql
-- 查找以元音字母开头的名字
SELECT name FROM users WHERE name REGEXP '^[aeiou]';
-- 查找包含非字母字符的产品名
SELECT product_name FROM products WHERE product_name REGEXP '[^a-zA-Z]';
4. 使用"或"逻辑
sql
-- 查找姓氏为 Smith、Johnson 或 Williams 的员工
SELECT * FROM employees WHERE last_name REGEXP 'Smith|Johnson|Williams';
-- 查找以 "Mr." 或 "Ms." 开头的称呼
SELECT title FROM contacts WHERE title REGEXP '^Mr\\.|^Ms\\.';
5. 匹配数字模式
sql
-- 查找描述中包含 "item" 后跟至少一个数字的订单
SELECT * FROM orders WHERE order_description REGEXP 'item[0-9]+';
-- 查找电话号码(假设格式为 11 位纯数字)
SELECT phone FROM users WHERE phone REGEXP '^[0-9]{11}$';
6. 区分大小写匹配
sql
-- 仅匹配小写 "apple"
SELECT * FROM products WHERE product_name REGEXP BINARY '^apple$';
-- 区分大小写的邮箱验证
SELECT email FROM users WHERE email REGEXP BINARY '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$';
四、REGEXP vs LIKE 对比
| 特性 | LIKE |
REGEXP |
|---|---|---|
| 通配符 | %(任意多字符),_(单字符) |
完整正则语法 |
| 灵活性 | 低 | 高 |
| 性能 | 快 | 慢 |
| 大小写 | 取决于列排序规则 | 默认不区分,可用 BINARY 控制 |
| 适用场景 | 简单模糊搜索 | 复杂模式匹配、格式验证 |
建议:
- 简单前缀/后缀匹配用
LIKE(如name LIKE 'John%');- 复杂规则(如邮箱、身份证、自定义格式)用
REGEXP。
五、性能与优化建议
-
避免在大表上频繁使用 REGEXP
REGEXP 无法使用普通索引,通常导致全表扫描,性能较差。
-
优先用 LIKE + 索引
若能用
LIKE 'prefix%'实现,务必优先使用。 -
结合其他条件缩小范围
sql-- 先用索引字段过滤,再用 REGEXP SELECT * FROM logs WHERE create_date > '2026-01-01' AND message REGEXP 'ERROR.*timeout'; -
考虑生成列 + 索引
对高频正则字段,可创建生成列并建索引:
sqlALTER TABLE users ADD COLUMN is_valid_email BOOLEAN AS (email REGEXP '^[^@]+@[^@]+\\.[^@]+$'), ADD INDEX idx_valid_email (is_valid_email);
六、PHP 脚本中使用 REGEXP
php
<?php
$conn = mysqli_connect('localhost', 'root', '123456');
mysqli_query($conn, "SET NAMES utf8mb4");
mysqli_select_db($conn, 'mydb');
// 用户输入关键词(需转义特殊字符!)
$keyword = mysqli_real_escape_string($conn, $_GET['search'] ?? '');
// 安全构建 REGEXP 模式(避免注入)
$sql = "SELECT * FROM articles
WHERE title REGEXP ?";
// 使用预处理语句(推荐)
$stmt = mysqli_prepare($conn, $sql);
// 注意:MySQL 预处理不支持直接绑定 REGEXP 模式,
// 通常需在应用层拼接(确保已转义)
$sql_safe = "SELECT * FROM articles WHERE title REGEXP '" . addslashes($keyword) . "'";
$result = mysqli_query($conn, $sql_safe);
while ($row = mysqli_fetch_assoc($result)) {
echo htmlspecialchars($row['title']) . "<br>";
}
?>
注意:
正则模式不能直接用预处理参数绑定,必须在应用层严格校验或转义用户输入,防止正则注入(ReDoS)攻击。
七、常见误区与注意事项
-
REGEXP不等于=
'abc' REGEXP 'ab'返回1(因为 "ab" 是 "abc" 的子串),而'abc' = 'ab'为0。 -
空字符串匹配
任何字符串都匹配空正则:
'hello' REGEXP ''→1。 -
NULL 值处理
若列值为
NULL,REGEXP返回NULL(在WHERE中视为FALSE)。 -
不支持完整 PCRE
MySQL 的正则引擎较简单,不支持
\d,\w,\s, 分组捕获()等高级特性(仅支持基本 POSIX ERE)。
小结
适合场景:
- 验证数据格式(邮箱、手机号、ID 编码);
- 提取符合特定结构的记录;
- 复杂文本模式匹配。
不适合场景:
- 简单关键词搜索(用
FULLTEXT或LIKE); - 高频查询的大表(性能瓶颈);
- 需要返回匹配位置或替换内容。
"简单模糊用 LIKE,复杂规则 REGEXP;性能敏感慎使用,安全转义莫忘记。"
掌握 MySQL 正则表达式,让你的查询从"能用"迈向"精准高效"。在合适的场景下,它将成为你 SQL 工具箱中的利器!