MySQL 知识量:16 - 40 - 165
正则表达式是用来匹配文本的特殊字符串的。它是一个文本处理工具,专门用来进行文本的特殊操作,例如找到重复的单词,提取文本中所有的数字等。它比通配符的功能要强大的多,这也正是它的优势所在。
正则表达式由正则表达式语言构建,正则表达式语言是一种特殊的语言,语法上也很特别,它小巧又复杂。
要学习正则表达式的详细内容,可以点击这里。
要在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”将不再满足条件。
如前所述,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',将没有数据被匹配,因为已经区分大小写了。
如果要查询两个字符串之一(或者是第一个串,或是是第二个串),可以使用“|”。
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'),因为正则表达式将后续部分一律视为字符串进行处理。
要匹配一组字符中一个字符时,可以使用“[”和“]”。
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 | +----+-------+-----+------+
从以上代码可以看出,“[]”实际就是“|”的另一种形式,但是在可选的字符较多时,[]更加直观和便于修改。
如果要反选结果,即否定匹配条件时,可以使用“^”。例如:
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 | +----+-------+-----+--------+
如果要匹配的字符包含在一个集合中,为了便于定义集合,可使用指定集合范围的方式。例如:[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 | +----+-------+-----+--------+
如果要在正则表达式的查询中查询像“.”、“|”之类的特殊字符时,就需要对这些字符进行转义。具体的办法是使用“\\”作为前导,在其他语言中,可能只需要一个“\”作为前导就行,但在MySQL中必须是“\\”。
\\. 表示匹配“.”
\\| 表示匹配“|”
\\\ 表示匹配“\”本身。
此外,“\\”还可以用来引用元字符:
\\f 表示换页
\\n 表示换行
\\r 表示回车
\\t 表示制表
\\v 表示纵向制表
在正则表达式语言中,存在一种预定义的字符集,称之为字符类。可以在查询中直接使用这些定义好的集合,以提高书写效率。
类 | 说明 |
---|---|
[: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]) |
在使用正则表达式进行匹配时,有时需要控制匹配字符出现的次数,这时可以使用重复元字符。
元字符 | 说明 |
---|---|
* | 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 | +----+-------+-----+------+
定位符用于匹配字符串中特定位置的字符。定位元字符包括:
^ 表示文本的开始
$ 表示文本的结束
[[:<:]] 表示词的开始
[[:>:]] 表示词的结尾
select * from student where name regexp '^j[a-z]*e$';
查询姓名包含由j开头,后跟a到z中任意个字符,以e结尾的学生信息。结果为:
+----+------+-----+------+ | id | name | age | sex | +----+------+-----+------+ | 2 | Jame | 12 | male | +----+------+-----+------+
如果要快速的测试正则表达式,在不设计表的情况下,可以使用select语句实现,例如:
select 'bob000' regexp '[0]{3}';
结果为:
+--------------------------+ | 'bob000' regexp '[0]{3}' | +--------------------------+ | 1 | +--------------------------+
其中,1表示匹配,如果返回的是0,则表示不匹配。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6