MySQL

MySQL 知识量:16 - 40 - 165

4.4 正则表达式><

什么是正则表达式- 4.4.1 -

正则表达式是用来匹配文本的特殊字符串的。它是一个文本处理工具,专门用来进行文本的特殊操作,例如找到重复的单词,提取文本中所有的数字等。它比通配符的功能要强大的多,这也正是它的优势所在。

正则表达式由正则表达式语言构建,正则表达式语言是一种特殊的语言,语法上也很特别,它小巧又复杂。

要学习正则表达式的详细内容,可以点击这里

基本字符匹配- 4.4.2 -

要在MySQL中使用正则表达式,需要用到“regexp”,它表示其后的字符串作为正则表达式来处理。例如:

select * from student where name regexp 'n';

查询名字中含有字母“n”的学生信息。结果为:

+----+-------+-----+--------+
| id | name  | age | sex    |
+----+-------+-----+--------+
|  1 | Susan |  11 | female |
|  5 | Jen   |  11 | female |
|  6 | Toney |  10 | male   |
+----+-------+-----+--------+

以上语句的效果与使用like加通配符一样,但是,如果修改为like 'n',就不会返回任何结果了,这正是它们之间的区别。regexp 'n'表示含有“n”就算匹配。

另一个例子:

select * from student where name regexp '.ob';

查询名字由?ob组成的学生信息。结果为:

+----+-------+-----+------+
| id | name  | age | sex  |
+----+-------+-----+------+
|  3 | Bob   |  11 | male |
|  4 | Robot |  10 | male |
+----+-------+-----+------+

正则表达式中的“.”表示匹配任意一个字符,与通配符“_”功能类似。

以上代码表示只要满足任意一个字符与ob组合都是匹配的。如果换成like '_ob',将只能查询到一行记录,“Robot”将不再满足条件。

区分大小写- 4.4.3 -

如前所述,SQL语句默认不区分大小写,如果在查询中需要区分大小写,可以使用“binary”关键字,将binary放到要区分大小写的匹配字符前面即可。例如:

 select * from student where name regexp binary 'J';

结果为:

+----+------+-----+--------+
| id | name | age | sex    |
+----+------+-----+--------+
|  2 | Jame |  12 | male   |
|  5 | Jen  |  11 | female |
+----+------+-----+--------+

如果将'J'换为'j',将没有数据被匹配,因为已经区分大小写了。

OR匹配- 4.4.4 -

如果要查询两个字符串之一(或者是第一个串,或是是第二个串),可以使用“|”。

select * from student where age regexp '11|12';

查询年龄为11岁或者为12岁的学生信息。结果为:

+----+-------+-----+--------+
| id | name  | age | sex    |
+----+-------+-----+--------+
|  1 | Susan |  11 | female |
|  2 | Jame  |  12 | male   |
|  3 | Bob   |  11 | male   |
|  5 | Jen   |  11 | female |
+----+-------+-----+--------+

需要注意的是:正则表达式的匹配字符串即使在表中是以数字方式存储的,在使用正则表达式时也要用引号括起来(例如上面的'11|12'),因为正则表达式将后续部分一律视为字符串进行处理。

匹配几个字符之一- 4.4.5 -

要匹配一组字符中一个字符时,可以使用“[”和“]”。

select * from student where name regexp 'o[bnt]';

查询姓名含有“ob”或“on”或“ot”的学生信息。其中,'o[bnt]'与'o[b|n|t]'的含义是一样的。结果为:

+----+-------+-----+------+
| id | name  | age | sex  |
+----+-------+-----+------+
|  3 | Bob   |  11 | male |
|  4 | Robot |  10 | male |
|  6 | Toney |  10 | male |
+----+-------+-----+------+

从以上代码可以看出,“[]”实际就是“|”的另一种形式,但是在可选的字符较多时,[]更加直观和便于修改。

否定匹配- 4.4.6 -

如果要反选结果,即否定匹配条件时,可以使用“^”。例如:

select * from student where name regexp '[^robt]';

查询姓名中含有“r、o、b、t”以外字符的学生信息。结果为:

+----+-------+-----+--------+
| id | name  | age | sex    |
+----+-------+-----+--------+
|  1 | Susan |  11 | female |
|  2 | Jame  |  12 | male   |
|  5 | Jen   |  11 | female |
|  6 | Toney |  10 | male   |
+----+-------+-----+--------+

匹配范围- 4.4.7 -

如果要匹配的字符包含在一个集合中,为了便于定义集合,可使用指定集合范围的方式。例如:[0-9]表示从0到9十个数字的集合;[a-z]表示从a到z的26个字母的集合。

select * from student where name regexp '[a-c]';

查询姓名中包含从a到c(a、b、c)三个字母中任意一个的学生信息。结果为:

+----+-------+-----+--------+
| id | name  | age | sex    |
+----+-------+-----+--------+
|  1 | Susan |  11 | female |
|  2 | Jame  |  12 | male   |
|  3 | Bob   |  11 | male   |
|  4 | Robot |  10 | male   |
+----+-------+-----+--------+

匹配特殊字符- 4.4.8 -

如果要在正则表达式的查询中查询像“.”、“|”之类的特殊字符时,就需要对这些字符进行转义。具体的办法是使用“\\”作为前导,在其他语言中,可能只需要一个“\”作为前导就行,但在MySQL中必须是“\\”。

  • \\. 表示匹配“.”

  • \\| 表示匹配“|”

  • \\\ 表示匹配“\”本身。

此外,“\\”还可以用来引用元字符:

  • \\f 表示换页

  • \\n 表示换行

  • \\r 表示回车

  • \\t 表示制表

  • \\v 表示纵向制表

匹配字符类- 4.4.9 -

在正则表达式语言中,存在一种预定义的字符集,称之为字符类。可以在查询中直接使用这些定义好的集合,以提高书写效率。

说明
[:alnum:]任意字母和数字([a-zA-Z0-9])
[:alpha:]任意字符([a-zA-Z])
[:digit:]任意数字([0-9])
[:lower:]任意小写字母([a-z])
[:upper:]任意大写字母([A-Z])
[:blank:]空格和制表(\\t)
[:space:]包括空格在内的任意空白字符([\\f\\n\\r\\t\\v])
[:cntrl:]ASCII控制字符(ASCII0到31和127)
[:print:]任意可打印字符
[:graph:]与[:print:]相同,但不包括空格
[:punct:]既不在[:alnum:]中,又不在[:cntrl:]中的任意字符
[:xdigit:]任意十六进制数字([a-fA-F0-9])

匹配多个实例- 4.4.10 -

在使用正则表达式进行匹配时,有时需要控制匹配字符出现的次数,这时可以使用重复元字符。

元字符说明
*0个或多个匹配
+1个或多个匹配
?0个或1个匹配
{n}n个匹配
{n,}不少于n个匹配
{n,m}n到m个匹配(m不超过255)

查询姓名包含一个o,后紧跟一个或多个任意字符,后紧跟0个或1个o的学生信息:

select * from student where name regexp 'o{1}[[:alpha:]]+o?';

结果为:

+----+-------+-----+------+
| id | name  | age | sex  |
+----+-------+-----+------+
|  3 | Bob   |  11 | male |
|  4 | Robot |  10 | male |
|  6 | Toney |  10 | male |
+----+-------+-----+------+

定位符- 4.4.11 -

定位符用于匹配字符串中特定位置的字符。定位元字符包括:

  • ^ 表示文本的开始

  • $ 表示文本的结束

  • [[:<:]] 表示词的开始

  • [[:>:]] 表示词的结尾

select * from student where name regexp '^j[a-z]*e$';

查询姓名包含由j开头,后跟a到z中任意个字符,以e结尾的学生信息。结果为:

+----+------+-----+------+
| id | name | age | sex  |
+----+------+-----+------+
|  2 | Jame |  12 | male |
+----+------+-----+------+

快速测试- 4.4.12 -

如果要快速的测试正则表达式,在不设计表的情况下,可以使用select语句实现,例如:

select 'bob000' regexp '[0]{3}';

结果为:

+--------------------------+
| 'bob000' regexp '[0]{3}' |
+--------------------------+
|                        1 |
+--------------------------+

其中,1表示匹配,如果返回的是0,则表示不匹配。