5.3.4.7 模式匹配
MySQL 提供标准的 SQL 模式匹配以及类似 Unix 工具如 vi, grep 和 sed 使用的扩展正则表达式。
SQL 模式匹配使您可以使用 _ 匹配任何单个字符,并使用 % 匹配任意数量的字符(包括零个字符)。在 MySQL 中,SQL 模式匹配默认是区分大小写的。以下是一些示例。请不要使用 = 或 <> 当使用 SQL 模式匹配时。相反,请使用 LIKE 或 NOT LIKE 比较运算符。
要找到以 b 开头的名字:
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
要找到以 fy 结尾的名字:
mysql> SELECT * FROM pet WHERE name LIKE '%fy';
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
要找到包含 w 的名字:
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
要找到长度为五个字符的名字,请使用五个 _ 模式字符:
mysql> SELECT * FROM pet WHERE name LIKE '_____';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
另一种类型的模式匹配由 MySQL 提供,使用类似于 Unix 工具的扩展正则表达式。当您测试此类模式是否匹配时,请使用 REGEXP_LIKE() 函数(或 REGEXP 或 RLIKE 运算符,它们是 REGEXP_LIKE() 的同义词)。
以下是扩展正则表达式的一些特点:
-
.匹配任何单个字符。 -
一个字符集
[...]匹配字符集中任何字符。例如,[abc]匹配a,b或c。要命名字符范围,请使用破折号。[a-z]匹配任何字母,而[0-9]匹配任何数字。 -
*匹配零个或多个前面的东西。例如,x*匹配任意数量的x字符,[0-9]*匹配任意数量的数字,而.*匹配任何内容的任意数量。 -
正则表达式模式匹配如果模式在要测试的值中匹配,就成功。这与
LIKE模式匹配不同,后者只有当模式完全匹配整个值时才成功。 -
要将模式锚定到要测试的值的开始或结束处,请在模式的开始使用
^或在模式的末尾使用$。
为了演示扩展正则表达式是如何工作的,将之前使用 LIKE 查询重写为使用 REGEXP_LIKE()。
要找到以 b 开头的名字,请使用 ^ 匹配名字的开始:
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b');
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1979-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
为了强制正则表达式比较为区分大小写,请使用区分大小写的排序规则,或者将一个字符串转换为二进制字符串,或指定 c 匹配控制字符。每个查询都只匹配小写 b 在名字的开始处:
SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b' COLLATE utf8mb4_0900_as_cs);
SELECT * FROM pet WHERE REGEXP_LIKE(name, BINARY '^b');
SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b', 'c');
要找到以 fy 结尾的名字,请使用 $ 匹配名字的结束:
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, 'fy$');
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
要找到包含 w 的名字,请使用以下查询:
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, 'w');
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
由于正则表达式模式匹配如果它出现在值中任何地方都能成功,因此在前一个查询中不需要在模式周围放置通配符来使其完全匹配整个值,就像 LIKE 模式那样。
要找到长度为五个字符的名字,请使用 ^ 和 $ 匹配名字的开始和结束,以及五个 . 在之间:
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^.....$');
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
您也可以使用 {(“重复-n}n-次”)运算符来写前一个查询:
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^.{5}$');
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
有关正则表达式语法的更多信息,请参阅 第 14.8.2 节,“Regular Expressions”。