正则表达式在MySQL5.7和MySQL8.0中的用法以及区别(三)
各位客官姥爷好,欢迎回来。我们上节给出了正则表达式在MySQL5.7与MySQL8.0中用法的区别(二),下面我们将继续正则表达式在Mysql数据库中使用系列内容。
准备工作
在之前的测试过程中,我们没有使用任何数据库表,在本节我们将创建一个test数据库,并在该数据库中创建一个user表。(5.7版本和8.0版本均进行以下过程)
1. 创建test数据库(需开启Mysql服务并成功登陆)
create database test;
2. 使用该数据库(光创建好了不行,得用起来,才能在这个数据库里创建表)
use test;
3. 创建user表
create table user(
id int auto_increment primary key,
name varchar(20) not null,
age int not null,
sex enum('female','male'));
4. 插入测试数据
insert into user(name,age,sex)
values('清风',22,'male'),
('John',30,'male'),
('Lisa',23,'female'),
('李清1',26,'male'),
('李清2',26,'female'),
('Bella',28,'female'),
('すずらん',33,'female'),
('さわやか風',20,'male');
select * from user;
到这里,测试数据就创建好了,下面我们开始正则表达式部分内容吧。
元字符
1. [\u4e00-\u9fa5]:unicode编码汉字
5.7版本
既然这里是unicode编码,那么我们先通过建表语句看下5.7版本的默认字符编码。
show create table user\G
可以看到这里是utf8,而utf8是unicode编码的一种,这样看起来似乎用[\u4e00-\u9fa5]去匹配汉字是没毛病的。
我们上节内容在没有使用数据库表时,使用的是select 字符 regexp '正则表达式' 这个语法,那么想把这个用法应用到数据库表的查询中,该如何使用呢?
select * from 表名 where 条件
我们直接把where中的条件替换为字符 regexp 正则表达式即可,而where条件会返回为True的记录(0等价于False,1等价于True),到这里用法基本了解了,下面来看一个示例。
示例:匹配用户名包含汉字的记录
select * from user where name regexp '[\u4e00-\u9fa5]';
匹配的结果中有全部为英文的,看起来5.7版本对这种用法并不友好。
不过,仔细观察的话会发现一个很有意思的事:ID为1,7,8这些记录没有被匹配到,而这3个里都没有字母和数字,这似乎从另一个角度说明如果保证数据只有汉字、数字以及字母的条件下,可以使用以下用法匹配全为汉字的部分。
name not regexp '[\u4e00-\u9fa5]'
如果上面没有日文,这里则只返回清风,李清1和李清2这种不全为汉字的没有被返回。(另外需要注意的是,如果在汉字中夹杂着符号,使用该用法时同样会被返回)
那么,到底怎么直接匹配到汉字呢?这里就需要借助UTF8汉字编码对照表,既然你5.7版本对unicode形式不友好,那我试试其中的16进制形式。
这里需要借助16进制转换函数HEX()把字符转换成16进制。
select * from user where hex(name) regexp 'e[4-9][0-9a-f]{4}';
返回的结果正是我们想要的。
8.0版本
同样的,我们先来看建表时默认的字符编码
select * from user where name regexp '[\u4e00-\u9fa5]';
结果和5.7版本的一致,但结合之前小节的内容,这里做一个尝试:替换\u为\\u
select * from user where name regexp '[\\u4e00-\\u9fa5]';
没想到这样居然可以,接下来再测试下16进制能不能用
select * from user where hex(name) regexp 'e[4-9][0-9a-f]{4}';
完美匹配。
2. 限定组(*、+、?、{n,})
示例:匹配name包含ll的记录
select * from user where name regexp 'l{2}';
这里5.7版本和8.0版本用法一致。
3. 位置组(^、$)
示例:返回姓李的用户的记录
select * from user where name regexp '^李';
这里5.7版本和8.0版本用法一致。
4. 位置组(\b)
5.7版本
通过之前的内容,相信不少客官姥爷都能猜到这里不会匹配到任何记录。
select * from user where name regexp '\bJohn\b';
对于单词的开始或者结尾,5.7版本有自己独特的用法。
[[:<:]]表示单词的开始,[[:>:]]表示单词的结尾
select * from user where name regexp '[[:<:]]John[[:>:]]';
8.0版本
对于8.0版本,则直接加斜杠即可。
select * from user where name regexp '\\bJohn\\b';
以上就是本次的分享,正则表达式之数据库系列正在进行中,欢迎各位客官姥爷关注我,方便您第一次时间收到【干货】!