正则表达式的作用是匹配文本,将一个正则表达式与一个文本串进行比较。MySQL用WHERE子句对正则表达式提供了支持,允许你指定正则表达式,过滤SELECT检索出的数据。
MySQL仅支持部分正则表达式。
SELECT 列名 FROM 表名 REGEXP 正则表达式;
基本字符匹配
假设有一张表computer_products
:
id | product | price |
---|---|---|
1 | 耳机 | 159 |
2 | 鼠标 | 199 |
3 | 键盘 | 659 |
4 | 显示器 | 899 |
以正则表达式匹配表中以99
结尾的商品:
mysql> SELECT * FROM computer_products WHERE price REGEXP '.99';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 2 | 鼠标 | 199 |
| 4 | 显示器 | 899 |
+----+---------+-------+
2 rows in set (0.00 sec)
.是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符,因此,199
和899
都匹配
且返回。
MySQL中的正则表达式匹配不区分大小写,大写和小写都匹配。为区分大小写,可在
REGEXP
后使用BINARY
关键字。
或(|)匹配
以正则表达式匹配表中价格为159
或199
的商品:
mysql> SELECT * FROM computer_products WHERE price REGEXP '159|199';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 1 | 耳机 | 159 |
| 2 | 鼠标 | 199 |
+----+---------+-------+
2 rows in set (0.00 sec)
|
为正则表达式的OR
操作符。它表示匹配其中之一,因此159
和199
都匹配并返回。
使用|
从功能上类似于在SELECT
语句中使用OR
语句,多个OR
条件可并入单个正则表达式。
匹配字符集合中几个字符之一
以正则表达式匹配表中价格为159
、659
、859
的商品:
mysql> SELECT * FROM computer_products WHERE price REGEXP '[168]59';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 1 | 耳机 | 159 |
| 3 | 键盘 | 659 |
+----+---------+-------+
2 rows in set (0.00 sec)
这里,使用了正则表达式[168]59
。[168]
定义一组字符,它的意思是匹配1
或6
或8
,因此,159
和659
都匹配且返回,没有859
,因此没有返回。
[]
是另一种形式的OR
语句。正则表达式[168]59
为[1|6|8]59
的缩写,也可以使用后者。但必须使用[]
包裹。
如果不使用[]
包裹时,结果如下:
mysql> SELECT * FROM computer_products WHERE price REGEXP '1|6|859';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 1 | 耳机 | 159 |
| 2 | 鼠标 | 199 |
| 3 | 键盘 | 659 |
+----+---------+-------+
3 rows in set (0.00 sec)
两个期望的行被检索出来,但还检索出了另外1行。之所以这样是由于MySQL认为检索条件是1
或6
或859
。
匹配范围
集合可用来定义要匹配的一个或多个字符。例如使用[0123456789]
表示匹配0~9
,这个表达式可以简写为[0-9]
。同样范围不一定是数字,也可以是[a-Z]
来匹配任意字符。
例如:
mysql> SELECT * FROM computer_products WHERE price REGEXP '[0-9]59';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 1 | 耳机 | 159 |
| 3 | 键盘 | 659 |
+----+---------+-------+
2 rows in set (0.00 sec)
匹配特殊字符
为了匹配特殊字符,必须用\\
进行转义。\\-
表示查找-
,\\.
表示查找.
。正则表达式内具有特殊意义的所有字符都必须以这种方式转义。
\\
也用来转义元字符,包括:
元字符 | 说明 |
---|---|
\\f | 换页 |
\\n | 换行 |
\\r | 回车 |
\\t | 制表 |
\\v | 纵向制表 |
为了匹配反斜杠(\)本身,需要使用
\\\
来转义。
匹配多个字符
之前的所有正则表达式都试图匹配单次出现,当需要匹配多次出现时,需要使用重复元字符。
元字符 | 说明 |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配,等同于{1,} |
? | 0个或1个匹配 ,等同于{0,1} |
{n} | 指定个数的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围,m不超过255 |
例如匹配包含**9
的商品:
mysql> SELECT * FROM computer_products WHERE price REGEXP '[0-9]*9';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 1 | 耳机 | 159 |
| 2 | 鼠标 | 199 |
| 3 | 键盘 | 659 |
| 4 | 显示器 | 899 |
+----+---------+-------+
4 rows in set (0.00 sec)
定位符
前面所有例子都是匹配一个组字符串中任意位置的字符。为了匹配特定位置的文本,需要使用下表中列出的定位符。
元字符 | 说明 |
---|---|
^ | 文本的开始 |
$ | 文本的结束 |
以匹配用9结尾的商品为例:
mysql> SELECT * FROM computer_products WHERE price REGEXP '[0-9]*9$';
+----+---------+-------+
| id | product | price |
+----+---------+-------+
| 1 | 耳机 | 159 |
| 2 | 鼠标 | 199 |
| 3 | 键盘 | 659 |
| 4 | 显示器 | 899 |
+----+---------+-------+
4 rows in set (0.00 sec)
可以在不使用数据库和表的情况下在MySQL中测试正则表达式,例如:
mysql> SELECT 'hello' REGEXP '^[a-z]{4}o$';
+------------------------------+
| 'hello' REGEXP '^[a-z]{4}o$' |
+------------------------------+
| 1 |
+------------------------------+
1 row in set (0.00 sec)