📌 目录

  1. MySQL 正则表达式概述
  2. 使用 REGEXP 进行字符串匹配
  3. 常见正则表达式模式
    • 匹配单个字符
    • 匹配多个字符
    • 匹配开始和结束
    • 匹配重复次数
    • 匹配分组
  4. MySQL REGEXP_LIKE() 函数
  5. MySQL REGEXP_REPLACE() 函数
  6. MySQL REGEXP_INSTR() 函数
  7. MySQL REGEXP_SUBSTR() 函数
  8. 实用示例
  9. 性能优化建议
  10. 参考资料

MySQL 正则表达式概述

MySQL 提供了 REGEXP 运算符来支持基于正则表达式的字符串匹配。从 MySQL 8.0.4 开始,MySQL 还提供了多个 REGEXP_ 函数,使正则表达式处理更加强大。

📌 主要用途

  • 搜索复杂字符串模式(如匹配邮箱、手机号、特定格式文本)。
  • 文本提取(如从日志或数据表中提取特定信息)。
  • 数据清理(如替换无效字符、去除多余空格)。

使用 REGEXP 进行字符串匹配

基本语法

SELECT column_name FROM table_name WHERE column_name REGEXP 'pattern';

示例:匹配包含 “abc” 的数据

SELECT * FROM users WHERE name REGEXP 'abc';

📌 该查询会返回 name 字段中包含 "abc" 的所有记录,如 "abcdef""xyzabc"

示例:匹配以 “A” 或 “B” 开头的用户名

SELECT * FROM users WHERE name REGEXP '^[AB]';

📌 ^ 表示字符串的开始位置[AB] 表示匹配 AB

示例:匹配以 “com” 结尾的邮箱

SELECT * FROM users WHERE email REGEXP 'com$';

📌 $ 表示字符串的结束位置


常见正则表达式模式

符号描述示例
.任意单个字符'a.c' 可匹配 "abc", "adc"
[...]匹配方括号内的任意字符'[aeiou]' 可匹配任何元音字母
[^...]匹配方括号内的字符'[^aeiou]' 匹配非元音字符
^匹配字符串开始位置'^abc' 匹配 "abc123" 但不匹配 "123abc"
$匹配字符串结束位置'xyz$' 匹配 "123xyz" 但不匹配 "xyz123"
``逻辑 OR,匹配左侧或右侧模式
*匹配前一个字符0 次或多次'ab*c' 可匹配 "ac", "abc", "abbc"
+匹配前一个字符1 次或多次'ab+c' 可匹配 "abc", "abbc" 但不匹配 "ac"
{n,m}指定重复次数'a{2,4}' 可匹配 "aa", "aaa", "aaaa"

MySQL REGEXP_LIKE() 函数

MySQL 8.0.4 之后,推荐使用 REGEXP_LIKE() 进行匹配查询。

语法

SELECT REGEXP_LIKE(string, pattern [, match_type]);

示例:匹配手机号(11 位数字)

SELECT * FROM users WHERE REGEXP_LIKE(phone, '^[0-9]{11}$');

📌 ^[0-9]{11}$ 解释

  • ^ 代表字符串开头
  • [0-9]{11} 代表 11 位数字
  • $ 代表字符串结束

MySQL REGEXP_REPLACE() 函数

用于替换字符串中符合正则表达式的部分

语法

SELECT REGEXP_REPLACE(string, pattern, replacement [, match_type]);

示例:去除邮箱中的特殊符号

SELECT REGEXP_REPLACE(email, '[^a-zA-Z0-9@.]', '') FROM users;

📌 作用:去掉 email 中的所有非字母、数字、@ 和 .


MySQL REGEXP_INSTR() 函数

返回匹配正则表达式的起始位置(索引从 1 开始)。

语法

SELECT REGEXP_INSTR(string, pattern [, start_pos [, match_type]]);

示例:查找邮箱中 @ 的位置

SELECT email, REGEXP_INSTR(email, '@') AS at_position FROM users;


MySQL REGEXP_SUBSTR() 函数

用于提取符合正则表达式的子字符串

语法

SELECT REGEXP_SUBSTR(string, pattern [, start_pos [, match_type]]);

示例:提取邮箱的域名

SELECT REGEXP_SUBSTR(email, '@[a-zA-Z0-9.-]+') FROM users;

📌 该查询会提取 @ 及其后的部分,如 @gmail.com


实用示例

1. 查找包含 “123” 或 “abc” 的用户名

SELECT * FROM users WHERE name REGEXP '123|abc';

2. 只匹配以 “M” 或 “N” 开头的姓名

SELECT * FROM users WHERE name REGEXP '^[MN]';

3. 查找手机号中包含非数字的记录

SELECT * FROM users WHERE phone NOT REGEXP '^[0-9]+$';


性能优化建议

  1. 避免大规模 REGEXP 查询
    • 正则匹配比 LIKE 查询慢,特别是对大数据表。
    • 尽量使用索引列进行 LIKE 查询,如:
    SELECT * FROM users WHERE name LIKE 'abc%';
  2. 使用 FULLTEXT 索引替代正则
    • 对长文本搜索,可考虑 FULLTEXT 索引:
    ALTER TABLE articles ADD FULLTEXT(title, content); SELECT * FROM articles WHERE MATCH(title, content) AGAINST ('database');

参考资料


如果你有更复杂的需求,欢迎继续讨论!🚀