SQL 中的正则表达式
正则表达式
正则表达式(Regular Expression,简称 Regex 或 Regexp)是一种用于匹配字符串中字符组合的模式。它们在文本处理、数据验证和搜索操作中非常有用。以下是一些常见的正则表达式及其用途:
一. 常见的正则表达式
1. 字符类
字符类用于匹配特定的字符集合。
-
.:匹配任何单个字符(除换行符外)。- 示例:
a.b匹配a后面跟着任何字符,再跟着b,如a1b、a-b。
- 示例:
-
[abc]:匹配方括号内的任意一个字符。- 示例:
[abc]匹配a、b或c。
- 示例:
-
[^abc]:匹配不在方括号内的任意一个字符。- 示例:
[^abc]匹配除a、b和c之外的任何字符。
- 示例:
-
[a-z]:匹配指定范围内的任意一个字符。- 示例:
[a-z]匹配任何小写字母。
- 示例:
-
[A-Z]:匹配任何大写字母。- 示例:
[A-Z]匹配任何大写字母。
- 示例:
-
[0-9]:匹配任何数字。- 示例:
[0-9]匹配任何单个数字。
- 示例:
2. 预定义字符类
预定义字符类是一些常用的字符类的简写形式。
-
\d:匹配任何数字,等价于[0-9]。- 示例:
\d匹配任何单个数字。
- 示例:
-
\D:匹配任何非数字字符,等价于[^0-9]。- 示例:
\D匹配任何非数字字符。
- 示例:
-
\s:匹配任何空白字符,包括空格、制表符、换行符等。- 示例:
\s匹配任何空白字符。
- 示例:
-
\S:匹配任何非空白字符。- 示例:
\S匹配任何非空白字符。
- 示例:
-
\w:匹配任何字母数字字符,等价于[a-zA-Z0-9_]。- 示例:
\w匹配任何字母数字字符或下划线。
- 示例:
-
\W:匹配任何非字母数字字符。- 示例:
\W匹配任何非字母数字字符。
- 示例:
3. 边界匹配
边界匹配用于匹配字符串的开始或结束位置。
-
^:匹配字符串的开始位置。- 示例:
^abc匹配以abc开头的字符串。
- 示例:
-
$:匹配字符串的结束位置。- 示例:
abc$匹配以abc结尾的字符串。
- 示例:
-
\b:匹配单词边界。- 示例:
\bword\b匹配完整的单词word,而不是word的子字符串。
- 示例:
4. 量词
量词用于指定前面的字符或字符类可以出现的次数。
-
*:匹配前面的字符或字符类 0 次或多次。- 示例:
a*匹配 0 个或多个a,如a、aa、aaa或空字符串。
- 示例:
-
+:匹配前面的字符或字符类 1 次或多次。- 示例:
a+匹配 1 个或多个a,如a、aa、aaa,但不匹配空字符串。
- 示例:
-
?:匹配前面的字符或字符类 0 次或 1 次。- 示例:
a?匹配 0 个或 1 个a,如a或空字符串。
- 示例:
-
{n}:匹配前面的字符或字符类恰好n次。- 示例:
a{3}匹配恰好 3 个a,如aaa。
- 示例:
-
{n,}:匹配前面的字符或字符类至少n次。- 示例:
a{3,}匹配 3 个或更多a,如aaa、aaaa。
- 示例:
-
{n,m}:匹配前面的字符或字符类至少n次,但不超过m次。- 示例:
a{2,4}匹配 2 到 4 个a,如aa、aaa、aaaa。
- 示例:
5. 分组和捕获
分组和捕获用于将正则表达式的一部分分组,并捕获匹配的内容。
-
():分组和捕获。- 示例:
(abc)匹配abc,并捕获匹配的内容。
- 示例:
-
(?:...):非捕获分组。- 示例:
(?:abc)匹配abc,但不捕获匹配的内容。
- 示例:
6. 选择
选择用于匹配多个模式中的一个。
|:选择。- 示例:
abc|def匹配abc或def。
- 示例:
7. 贪婪和非贪婪
量词的贪婪和非贪婪模式决定了匹配的长度。
-
贪婪模式:默认情况下,量词是贪婪的,尽可能多地匹配字符。
- 示例:
a+匹配尽可能多的a。
- 示例:
-
非贪婪模式:在量词后加
?,使其变为非贪婪模式,尽可能少地匹配字符。- 示例:
a+?匹配尽可能少的a。
- 示例:
8. 断言
断言用于指定匹配的条件,但不消耗字符。
-
前瞻断言:
- 正前瞻:
(?=...),匹配后面跟着指定模式的字符。- 示例:
abc(?=def)匹配abc,但只有在其后面跟着def时才匹配。
- 示例:
- 负前瞻:
(?!...),匹配后面不跟着指定模式的字符。- 示例:
abc(?!def)匹配abc,但只有在其后面不跟着def时才匹配。
- 示例:
- 正前瞻:
-
后顾断言:
- 正后顾:
(?<=...),匹配前面跟着指定模式的字符。- 示例:
(?<=abc)def匹配def,但只有在其前面跟着abc时才匹配。
- 示例:
- 负后顾:
(?<!...),匹配前面不跟着指定模式的字符。- 示例:
(?<!abc)def匹配def,但只有在其前面不跟着abc时才匹配。
- 示例:
- 正后顾:
示例
假设有一个字符串 123abc456def789,我们想匹配其中的数字和字母组合。
-
匹配数字:
\d+- 匹配结果:
123、456、789
- 匹配结果:
-
匹配字母:
[a-z]+- 匹配结果:
abc、def
- 匹配结果:
-
匹配数字和字母组合:
\d+[a-z]+- 匹配结果:
123abc、456def
- 匹配结果:
二. 使用语法
在 MySQL 中,可以使用 REGEXP 或 RLIKE 操作符来使用正则表达式。
语法:
REGEXP
SELECT column1, column2
FROM table_name
WHERE column1 REGEXP 'pattern';
RLIKE
SELECT column1, column2, ...
FROM table_name
WHERE column_name RLIKE 'pattern';
三. 使用 LIKE 和正则表达式的区别
-
LIKE操作符:- 适用于简单的模式匹配,支持
%和_两个通配符。 - 性能较好,适用于大多数简单的文本匹配需求。
- 适用于简单的模式匹配,支持
-
正则表达式:
- 适用于复杂的模式匹配,支持更广泛的模式匹配功能。
- 性能可能稍差,但在处理复杂模式时非常强大。
示例
假设有一个 employees 表,包含以下数据:
| 1 | Alice | Smith | 60000 | 101 |
| 2 | Bob | Johnson | 70000 | 101 |
| 3 | Charlie | Brown | NULL | 102 |
| 4 | David | Davis | 80000 | 102 |
| 5 | Eve | White | 90000 | 103 |
假设我们想查询名字以字母 "A" 开头,且名字长度为 5 个字符的员工。使用 LIKE 操作符可以这样写:
SELECT *
FROM employees
WHERE first_name LIKE 'A____';
结果:
| 1 | Alice | Smith | 60000 | 101 |
使用正则表达式可以这样写:
SELECT *
FROM employees
WHERE first_name REGEXP '^A.{4}$';
结果:
| 1 | Alice | Smith | 60000 | 101 |
总结
LIKE操作符:适用于简单的模式匹配,支持%和_通配符,性能较好。- 正则表达式:适用于复杂的模式匹配,支持更广泛的模式匹配功能,但性能可能稍差。
查看4道真题和解析
