Mysql中正则表达式Regexp常见用法
Mysql中Regexp常见用法
模糊匹配,包含特定字符串
#查找content字段中包含“车友俱乐部”的记录
select*fromclub_contentwherecontentregexp'车友俱乐部'
#此时的regexp与like的以下用法是等同的
select*fromclub_contentwherecontentlike'%车友俱乐部%'
模糊匹配,以特定字符串开头
#查找content字段中以“车友”开头的记录
select*fromclub_contentwherecontentregexp'^车友'
#此时的regexp与like的以下用法是等同的
select*fromclub_contentwherecontentlike'车友%'
模糊匹配,以特定字符串结尾
#查找content字段中以“车友”结尾的记录
select*fromclub_contentwherecontentregexp'车友$'
#此时的regexp与like的以下用法是等同的
select*fromclub_contentwherecontentlike'%车友'
模糊匹配,或关系
#查找content字段中包含“心得”、“分享”或“技术贴”
select*fromclub_contentwherecontentREGEXP'心得|分享|技术贴'
模糊匹配,不包含单个字符
#查找content字段中不包含“车”字、“友”字的记录
select*fromclub_contentwherecontentREGEXP[^车友]
这个结果跑出来一看大吃一惊,竟然把所有记录给跑出来,这是为什么呢?
因为一旦加了这个方括号"[]",它就把里面的内容拆成单个的字符再匹配,它会逐个字符去匹配判断是不是等于“车”,或者是不是等于“友“,返回的结果是一组0、1的逻辑值。
如果想匹配不包含特定字符串,该怎么实现呢?
模糊匹配,不包含特定字符串
#查找content字段不包含“车友”字符串的记录
select*fromclub_contentwherecontentnotREGEXP'车友'
MySqlREGEXP运算符匹配字符串
1^匹配以该字符后面的字符开头的字符串
举个例子:REGEXP‘^x'表示匹配以x开头的字符
2$匹配以该字符前面的字符结尾的字符串
举个例子:REGEXP‘y$'表示匹配以y结尾的字符
3.匹配任意一个字符
4[…]匹配在方括号中的任意一个字符。
如:[1-9]匹配1到9的数字,[abc]匹配其中任意一个
5*匹配零个或多个在它前面的字符
如:x*匹配任何数量的x字符
mysql如何判断"字符串"是否为"数字"
这个问题有点怪,但很多时候我们会以字符串的形式存储数字,反过来我们用字符串进行数学运算时,好像也不会出错.除非,用作数学运算的字符串不能转换成数字.
但是我们改如何判断字符串是否能转换成数字呢?
采用mysql的REGEXP运算符.怎么用?
{String}REGEXP'[^0-9.]'
前面的字符串是我们要做判断的,后面的字符串是mysql的正则表达式,意思是匹配不是数字或者小数点的字符。
如果String中含有不是0-9之间的数字或者是小数点时,返回true,反之则返回false。
比如说:
select('123a'REGEXP'[^0-9.]');--‘123a'中含有字符'a'输出结果为1mysql中常量true输出为1false输出为0
注意:如果字符串中有空格,也会匹配到正则表达式,返回1。如果是要去掉两端的空格,就要将判断的字符串,就要对字符串使用trim()函数了。
这个只是REGEXP操作符的简单应用,REGEXP的详细应用请参考官方文档。
MySQL正则表达式
在前面的章节我们已经了解到MySQL可以通过LIKE...%来进行模糊匹配。
MySQL同样也支持其他正则表达式的匹配,MySQL中使用REGEXP操作符来进行正则表达式匹配。
如果您了解PHP或Perl,那么操作起来就非常简单,因为MySQL的正则表达式匹配与这些脚本的类似。
下表中的正则模式可应用于REGEXP操作符中。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配'\n'或'\r'之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配'\n'或'\r'之前的位置。 |
. | 匹配除"\n"之外的任何单个字符。要匹配包括'\n'在内的任何字符,请使用象'[.\n]'的模式。 |
[...] | 字符集合。匹配所包含的任意一个字符。例如,'[abc]'可以匹配"plain"中的'a'。 |
[^...] | 负值字符集合。匹配未包含的任意字符。例如,'[^abc]'可以匹配"plain"中的'p'。 |
p1|p2|p3 | 匹配p1或p2或p3。例如,'z|food'能匹配"z"或"food"。'(z|f)ood'则匹配"zood"或"food"。 |
* | 匹配前面的子表达式零次或多次。例如,zo*能匹配"z"以及"zoo"。*等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+'能匹配"zo"以及"zoo",但不能匹配"z"。+等价于{1,}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,'o{2}'不能匹配"Bob"中的'o',但是能匹配"food"中的两个o。 |
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。 |
实例
了解以上的正则需求后,我们就可以根据自己的需求来编写带有正则表达式的SQL语句。以下我们将列出几个小实例(表名:person_tbl)来加深我们的理解:
查找name字段中以'st'为开头的所有数据:
mysql>SELECTnameFROMperson_tblWHEREnameREGEXP'^st';
查找name字段中以'ok'为结尾的所有数据:
mysql>SELECTnameFROMperson_tblWHEREnameREGEXP'ok$';
查找name字段中包含'mar'字符串的所有数据:
mysql>SELECTnameFROMperson_tblWHEREnameREGEXP'mar';
查找name字段中以元音字符开头或以'ok'字符串结尾的所有数据:
mysql>SELECTnameFROMperson_tblWHEREnameREGEXP'^[aeiou]|ok$';
mysql正则REGEXP学习练习笔记
REGEXP在mysql是用来执行正则表达式的一个函数,像php中的preg之类的函数了,regexp正则函数如果只是简单的查询使用like即可,但复杂的还是需要使用regexp了,下面我们来看看。
MySql用户手册建议,在构造简单查询时,仍使用通配符。
如:
Select[*|fieldnamelist]From[tablename]where[fieldname]like["%someletter"|"%someletter%","_","?someletter"];
但在一些特殊查询中,不用正则表达式是不行的。MYSQL提供的正则表达式WHERE谓词有三个,分别是:
REGEXP,RLIKE,NOTRLIKE
用这三个替换原有的LIKE谓词,后面即可以跟正则表达式。
例如要查询字段中含有“_”的数据,则要用以下查询语句:
SELECT*FROMTABLENAMEWHEREFIELDNAMERLIKE'.[_].';
扩展正则表达式的一些字符是:
·‘.'匹配任何单个的字符。
·字符类“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”、“b”或“c”。为了命名字符的范围,使用一个“-”。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。
·“*”匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的“x”字符,“[0-9]*”匹配任何数量的数字,而“.*”匹配任何数量的任何字符。
如果REGEXP模式与被测试值的任何地方匹配,模式就匹配(这不同于LIKE模式匹配,只有与整个值匹配,模式才匹配)。
为了定位一个模式以便它必须匹配被测试值的开始或结尾,在模式开始处使用“^”或在模式的结尾用“$”。
为了找出以“b”开头的名字,使用“^”匹配名字的开始:
使用正则
SELECT*FROMpetWHEREnameREGEXPBINARY‘^b';
SELECT*FROMpetWHEREnameREGEXP‘fy$';
SELECT*FROMpetWHEREnameREGEXP‘w';
SELECT*FROMpetWHEREnameREGEXP‘^…..$';
SELECT*FROMpetWHEREnameREGEXP‘^.{5}$';
今天在应用中遇到了这样的一个问题,
有一个字段t1,其中的值类似于:1,1,1,2,3,3,4,4,5,5,2,4,3,2,1,2
需要从里面搜索出比如说:第一个逗号前的数字范围为3-5之间,第三个逗号前的数字的范围为3-5之间,第10个逗号前的数字范围为3-5之间,其余的都为1-5之间。。。
则sql语句可以这么写:
SELECT*FROMtbWHEREt1REGEXP'^[3-5],[1-5],[3-5],[1-5],[1-5],[1-5],[1-5],[1-5],[1-5],[3-5],[1-5],[1-5],[1-5],[1-5],[1-5],[1-5]%';
1.使用LIKE和NOTLIKE比较操作符(注意不能使用=或!=);
2.模式默认是忽略大小写的;
3.允许使用”_”匹配任何单个字符,”%”匹配任意数目字符(包括零字符);
附一些mysql正则规则
^匹配字符串的开始部分
$匹配字符串的结束部分
.匹配任何字符(包括回车和新行)
a*匹配0或多个a字符的任何序列
a+匹配1个或多个a字符的任何序列
a?匹配0个或1个a字符
de|abc匹配序列de或abc
(abc)*匹配序列adc的0个或者多个实例
{n}、{m,n}{n}或{m,n}符号提供了编写正则表达式的更通用方式,能够匹配模式的很多前述原子(或“部分”)。m和n均为整数。
a*可被写为a{0,}
a+可被写为a{1,}
a?可被写为a{0,1}
[a-dX]匹配任何是a,b,c,d或者X的字符,两个其他字符之间的'-'字符构成一个范围
[^a-dX]匹配任何不是a,b,c,d或者X的字符,前面的字符'^'是否定的意思
[.characters.]在括号表达式中(使用[和]),匹配用于校对元素的字符序列,字符为单个字符或新行等字符名
mysql>SELECT‘~'REGEXP‘[[.~.]]';->1
mysql>SELECT‘~'REGEXP‘[[.tilde.]]';->1
[=character_class=]
在括号表达式中(使用[和]),[=character_class=]表示等同类。它与具有相同校对值的所有字符匹配,包括它本身,
[[=a=]]等同于[a(+)],[a+],[a{1,}]
[:character_class:]
在括号表达式中(使用[和]),[:character_class:]表示与术语类的所有字符匹配的字符类。
标准的类名称是:
alnum文字数字字符
alpha文字字符
blank空白字符
cntrl控制字符
digit数字字符
graph图形字符
lower小写文字字符
print图形或空格字符
punct标点字符
space空格、制表符、新行、和回车
upper大写文字字符
xdigit十六进制数字字符
[[:<:]],[[:>:]]
这些标记表示word边界。它们分别与word的开始和结束匹配。word是一系列字字符,其前面和后面均没有字字符。字符是alnum类中的字母数字字符或下划线(_)。
mysql>select‘fangshanzi'regexp‘[[:<:]]shan[[:>:]]';->1
mysql>select‘fangshanzi'regexp‘[[:<:]]fang[[:>:]]';->1
mysql>select‘fangshanszi'regexp‘[[:<:]]shan[[:>:]]';->0
正则表达式使用特殊字符,应在其前面加上2个反斜杠''字符
mysql>SELECT'1+2′REGEXP'1+2′;->0
mysql>SELECT'1+2′REGEXP'1+2′;->0
mysql>SELECT'1+2′REGEXP'1\+2′;->1
MySQL查寻条件使用正则regexp
我用的是Mybatis
t.hobby:条件字段
hobby :查寻参数,值可以是多个逗号分隔的值:‘阅读,交友,围棋'
concat(',',REPLACE(t.hobby,'',''),',')regexpconcat(',(',replace(#{hobby},',','|'),'),')
concat(',',REPLACE(' 吃, 喝,嫖,赌 ,抽,坑,蒙,拐,骗,偷','',''),',')regexpconcat(',(',replace(#{hobby},',','|'),'),')
concat(',','吃,喝,嫖,赌,抽,坑,蒙,拐,骗,偷',',')regexpconcat(',(',replace(#{hobby},',','|'),'),')
',吃,喝,嫖,赌,抽,坑,蒙,拐,骗,偷,'regexpconcat(',(',replace(#{hobby},',','|'),'),')
',吃,喝,嫖,赌,抽,坑,蒙,拐,骗,偷,'regexpconcat(',(',replace('吃,喝,嫖,嫖',',','|'),'),')
',吃,喝,嫖,赌,抽,坑,蒙,拐,骗,偷,'regexpconcat(',(','吃|喝|嫖|嫖','),')
',吃,喝,嫖,赌,抽,坑,蒙,拐,骗,偷,'regexp',(吃|喝|嫖|嫖),'
得到结果是1作为条件就是真了。
复杂的过程主要是用来处理查寻条件。得到符合要求的正则作条件就ok了
但个人觉得,更理想的方式是:
被查寻字段在当初存入数据时就处理好格式:'吃,喝,嫖,赌,抽,坑,蒙,拐,骗,偷'
查寻条件可以处理好传进来:',(吃|喝|嫖|嫖),'
那么一个查寻就可以简化成这样
concat(',',t.hobby,',')regexp#{hobby}
到这就差不多了,基本上就可以看得懂了,实在不行就参考下面的相关文章。