美文网首页
必知必会-第九章

必知必会-第九章

作者: 转身丶即天涯 | 来源:发表于2018-01-15 10:47 被阅读6次

    本章主要讲解,如何在where子句中使用正则表达式从而精确筛选数据。

    正则表达式干啥的?

    用来匹配文本的特殊串,比如从一段文本中提取邮箱和电话号码,再比如查找指定规则的文件名,再再比如将页面的URL替换为实际的HTML链接等等。

    Mysql中正则表达式

    mysql用where子句对正则表达式提供了初级支持,允许用你指定的正则表达式过滤select出来的数据。

    几个简单的例子

    找出address字段所有包含‘47’的行。


    image.png

    从上图可以看出,REGEXP和LIKE的用法很是相似。但是并没发现它的优势,继续看。

    找出address字段所有‘102’的行,可以是任何字符。

    image.png
    ‘.’字符可以匹配任何一个字符,所以匹配出来的结果中有‘1027’,‘1029’,‘102 ’(102空格)。
    当然这个功能用LIKE和通配符依然可以完成,那么我还用正则干什么呢?
    LIKE和REGEXP的区别

    LIKE只有在完全匹配的情况下才会返回值,而REGEXP是包含的情况下就能返回值。我看根据结果可以对比一下。


    image.png
    image.png
    image.png

    聪明的你,也许看完这三张图就都明白了。

    前面说过mysql在匹配结果时是忽略大小写的

    但是使用正则表达式就可以区分大小写,而不必修改mysql的配置,毕竟不是所有人都是DBA。
    为了区分大小写,可以使用BINARY关键字,比如where address REGEXP BINARY 'Beijing .000'。

    OR匹配
    image.png

    匹配address中所有包含‘47’或者‘35’的行。
    在逻辑表达中,‘|’表示或者,多个“或者”条件放在一起时,只要满足其中一个就返回值,所以,返回的数据集合应该是满足任何一个条件的合集。

    匹配特定的字符

    如果你想匹配特定的字符,需要给特定的字符设置一个字符集,用中括号[]表示,有点像我们编程时用的数组。


    image.png

    上图是想匹配,包含‘10’,‘11,‘12’,‘13’的address字段的值。
    其实这种方式也是一种OR,我们还可以这么写,REGEXP '10|11|12|13'。
    个人觉得分组看起来更清晰,而且随着匹配规则的愈加复杂,|会干扰逻辑运算,稍不注意就会影响我们筛选数据的结果。

    匹配范围

    仍然用到刚才的分组,比如你想匹配0-9的数字,[0-9].
    比如我想比配字符a,b,c,...,x,y,z,[a-z]。
    如果你想匹配0-3,6-9的范围,[0-36-9]。字符也是同理,这样进行范围匹配就很方便编写正则表达式了。
    例如我们常见的电话号码,QQ号,邮箱账号等等,都会用到。

    正则表达式中,特殊符号要转义

    我们知道.在正则表达式中,表示匹配任意一个字符,但是在字段的值中也很有可能出现,我想匹配值中的‘.’时,就需要转义。
    转义很简单,在‘.’前面加个'\'就行。
    其他需要转义的常见字符还有, . \ | [],以及下面这些元字符


    image.png
    转义时咋是两个斜杠?

    我们刚学C语言时,也听过或者用过转义,一般用一个\就搞定了,为什么mysql中需要两个?
    因为,这是mysql官方要求,其中一个\由mysql负责解析,另一个由正则表达式库来解析。
    大致原因如此,原理不详。

    mysql帮你定义好了的字符类

    下面是预定义的字符集,使用时可以参考下表


    image.png
    匹配多个实例

    之前的例子都是匹配单次出现,但是实际工作中会匹配多次出现的情况,所以我们要学会对出现次数的控制来强化我们的正则表达式。
    上一张书上的配图


    image.png

    要注意放置的次序,一般放在[]后面,字符串后面。

    比如,我想在city表中查找city字段中带(),并且括号中的英文字符数至少有8个的行。听起来有点拗口是吧?


    image.png

    然后我们解读一下REGEXP后面的内容吧,首先转义(,就是\(。
    然后用[]分组,确定英文字符的范围,小写a-z以及大写A-Z,就是[a-zA-Z]。
    然后用{}来控制字符出现的次数,{8,},表示出现8次或者8次以上。
    最后,再次转义,\)。

    这些正则还算是简单的,当你看到了更加复杂的正则表达式时,一定要慢慢看,逐字分析,不然心态很容易爆炸,尤其是和我一样的菜鸟,切记。

    匹配特定位置的文本

    之前我们学习的都是匹配任意位置的文本,现在我们要学习匹配特定位置的文本,比如以xxx开头,或者以xxx结尾,再或者以xxx开头中间包含ss,又以yy结尾的。
    匹配特定位置的文本的话,需要使用定位符,那么我们得知道都有什么定位符


    image.png

    那我们看一个简单的例子,找出以数字开头,并包含‘Drive’的行。
    我作了一个错误的示范,不要犯同样的错误哦。
    我把2个条件都写在了一个正则表达式里了,然后根本查不出数据来,如图:


    image.png

    然后仔细一读正则,发现了问题,图中的正则表示找出以数字drive开头的数据,当然,数据库中并不存在这样的数据。
    我想要的是包含drive,而不是从头匹配drive。这是两个条件,所以我们应该分开写,把regexp写在两个where子句中。


    image.png
    这样一来,我们想要筛选的数据就出来了。
    注意 ^

    ^有两种用途,第一种,表示从头匹配字符串。
    另一种,否定集合内容。[^1-5],表示,除了1-5的字符之外的字符,可以是6,7,8,a,b,c等等。

    好啦,第九章,搞定。

    相关文章

      网友评论

          本文标题:必知必会-第九章

          本文链接:https://www.haomeiwen.com/subject/wuhroxtx.html