MySQL正则表达式
正则表达式的作用
正则表达式也叫做匹配模式(Pattern),它由一组具有特定含义的字符串组成,通常用于匹配和替换文本。
正则表达式的语法
SELECT
column1,
column2,
…
FROM table_name
WHERE columnN REGEXP pattern;
正则表达式的关键字是REGEXP,后面接需要进行匹配的文本。
示例数据库
我们以customers表的数据为例:
表customers
简单的字符匹配
查找地址中含有12的记录,可以使用如下SQL:
SELECT * FROM customers
WHERE 地址 REGEXP '12'
结果为:
这和我们前面章节学的LIKE感觉没有多大区别,但是仔细看你会发现,如果直接把REGEXP换成LIKE是查找不到任何数据的,必须添加通配符’%'才可以实现相同功能。
这就是正则表达式REGEXP和LIKE的一个非常大的区别:
**REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现, REGEXP将会找到它,相应的行将被返回 。
**
我们再看下面一个例子
SELECT * FROM customers
WHERE 地址 REGEXP '12.'
结果为:
这里多了一个 .,它是正则表达式中的特殊字符。它表示匹配任意一个字符,类似LIKE里面的**_**。
OR匹配
查找地址中包含12或者17的记录,可以使用如下SQL:
SELECT * FROM customers
WHERE 地址 REGEXP '12|17'
结果为:
这里的 | 也是正则表达式中的特殊字符,表示或者的意思,类似OR语句。
匹配指定字符中的任意一个
查找地址中包含"京",“城”,"道"中的任意一个,可以这样写SQL:
SELECT * FROM customers
WHERE 地址 REGEXP '[京城道]'
结果为:
这里的 [] 也是正则表达式中的特殊字符,也是或者的意思。
匹配范围
当我们要匹配某个范围的的数据时,例如0123456789,可以简写成[0-9],
这里的特殊字符 -,表示某个区间的值。
查找地址中包含3-9的记录,可以这样写SQL:
SELECT * FROM customers
WHERE 地址 REGEXP '[3-9]'
结果为:
此外区间范围的不止有数值,字母也可以,例如[a-z],[A-Z]。
示例数据表
我们还是以表customers为例,这一次我们添加了一位外国朋友。
表customers
匹配特殊字符
正则表达式是由具有特定含义的特殊字符构成 ,我们已经用过 . 、[]、|、和-。如果我们需要匹配这些特殊字符该怎么办?
例如我们想找出customers表中姓名里带 . 的客户信息,该怎么写?
如果按这种写法:
SELECT * FROM customers
WHERE `姓名` REGEXP '.'
结果为:
与我们实际想找的客户信息不一致,这个时候我们就需要使用到一个新的特殊字符:\,我们称它为转义字符。
上面的需求我们就可以这样写:
SELECT * FROM customers
WHERE `姓名` REGEXP '\\.'
结果为:
结果与我们期望一致。
转义符不仅可以匹配我们需要的特殊字符,还可以元字符(具有特殊意义的字符)。
**元字符 ** | **说明 ** |
---|---|
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 制表 |
\v | 纵向制表 |
匹配字符类
正则表达式中还预定义了一些常用的字符集,这些我们成为字符类,可以方便我们直接使用。
**字符类 ** | **说明 ** |
---|---|
[:alnum:] | 任意字母或数字 |
[:alpha:] | 任意字母 |
[:blank:] | 空格和制表 |
[:cntrl:] | ASCII控制符 |
[:digit:] | 任意数字 |
[:graph:] | 与[:print:]相同,但不包含空格 |
[:lower:] | 任意小写字母 |
[:print:] | 任意可打印字符 |
[:punct:] | 既不在[:alnum:]也不在[:cntrl:]中的任意字符 |
[:space:] | 包含空格在内的任意空白字符 |
[:upper:] | 任意大写字母 |
[:xdigit:] | 任意十六进制数字 |
匹配多实例
前面我们讲解的都是单词匹配,如果要匹配多次该如何处理?下面我们介绍一下重复元字符,即可以实现字符的多次匹配。
**元字符 ** | **说明 ** |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配 |
? | 0个或1个匹配 |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围 |
例如我们要查找邮编里以1开头,0重复了5次的用户信息,可以这样写SQL:
SELECT * FROM customers
WHERE `邮编` REGEXP '10{5}'
结果为:
这里的{5}就是会将它前面的0重复5次。
定位符
上面的内容都是匹配任务位置的内容,如果我们需要匹配特定位置的内容,需要使用到定位符
**元字符 ** | **说明 ** |
---|---|
^ | 文本的开头 |
$ | 文本的结尾 |
[[:<:]] | 词的开头 |
[[:>:]] | 词的结尾 |
例如我们要找一个地址以"西"开头的用户,如果直接使用下面的SQL:
SELECT * FROM customers
WHERE `地址` REGEXP '西'
结果为:
虽然第二条记录中也有"西",但是并不是以"西"开头的,所以我们应该这样写才对:
SELECT * FROM customers
WHERE `地址` REGEXP '^西'
结果为:
以"西"开头的用户,如果直接使用下面的SQL:
SELECT * FROM customers
WHERE `地址` REGEXP '西'
结果为:
虽然第二条记录中也有"西",但是并不是以"西"开头的,所以我们应该这样写才对:
SELECT * FROM customers
WHERE `地址` REGEXP '^西'
结果为:
其他的元字符就不一一举例了。