3.3.4.7. 模式匹配
MySQL 提供标准的 SQL 模式匹配语法,同时也提供一种扩展的模式匹配语法,这种语法类似于在 Unix 中的 vi, grep, 和 sed工具中使用的正则表达式语法。
SQL 模式匹配允许你使用 ‘_
’ 来匹配一个单个的字符和 ‘%
’ 来匹配多个字符(包括0个字符)。在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 |
+----------+-------+---------+------+------------+------------+
查找刚好是5个字符的名字, 可以使用五个 ‘_
’ 模式字符:
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提供的另外一种模式匹配 使用扩展的正则表达式, 当测试是否和这种模式相匹配时, 使用REGEXP
和 NOT REGEXP
操作符 (或者RLIKE
和 NOT RLIKE
)。
扩展正则表达式的一些通配符号如下:
-
‘
.
’ 匹配所有单个字符。 -
一个字符集合 ‘
[...]
’ 匹配任何在这个集合中的字符。 例如, ‘[abc]
’ 匹配 ‘a
’, ‘b
’, 或 ‘c
’。 要指定一个范围的字符,可以使用一个破折号,如 ‘[a-z]
’匹配所有字母, 而 ‘[0-9]
’ 匹配所有数字。 -
‘
*
’ 匹配它前面的字符0到多遍, 例如,‘x*
’匹配任意个 ‘x
’ 字符, ‘[0-9]*
’ 匹配任意位数的数字, ‘.*
’ 匹配任意数量的任何字符。 - 一个
REGEXP
模式匹配操作只要字符串的匹配任何一处都算成功 。(这和LIKE
模式匹配不同,它只有当整个字符串都匹配的时候才算成功。) -
要指定一个模式必须和一个值的开头或结尾匹配,可在开头使用 ‘
^
’ 在结尾使用 ‘$
’ 。
下面的例子把前面例子中语句重写,不使用LIKE
而使用REGEXP
,来展示正则表达式的功能:
查找以 ‘b
’开头的名字, 使用 ‘^
’ 来匹配名字的开头:
mysql> SELECT * FROM pet WHERE name REGEXP '^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 |
+--------+--------+---------+------+------------+------------+
如果你确实想在进行REGEXP
比较时区分大小写, 可以使用BINARY
关键字让一个字符串成为二进制的字符串,这个查询配配以小写的 ‘b
’ 开头的名字:
mysql> SELECT * FROM pet WHERE name REGEXP BINARY '^b';
查找以‘fy
’结尾的名字,以 ‘$
’ 来匹配名字的结尾:
mysql> SELECT * FROM pet WHERE name REGEXP '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 REGEXP '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 |
+----------+-------+---------+------+------------+------------+
上面使用这则表达式匹配的例子和前面使用SQL模式匹配的例子不一样,因为正则表达式只要是在字符串中的任何地方匹配都算是跟整个字符串匹配,所以上面的例子不需要在'w'字符的两边加上通配符。
查找刚好只有五个字符的名字,使用 ‘^
’ 和 ‘$
’ 来匹配名字的开头和结尾,使用五个 ‘.
’ 来匹配中间的值:
mysql> SELECT * FROM pet WHERE name REGEXP '^.....$';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
你还可以使用{
(“repeat-n
}n
-times”) 操作符来写上面的查询:
mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Appendix G, MySQL Regular Expressions,提供了关于正则表达式符号的更多信息。
相濡以沫,不如相忘于江湖