美文网首页简书收藏--Python正则表达式Python程序员联盟
正则实战秘籍分享-学会了能让1小时的工作变成3分钟

正则实战秘籍分享-学会了能让1小时的工作变成3分钟

作者: 菜鸟学python | 来源:发表于2017-01-12 21:28 被阅读382次

    这是菜鸟学python的第46篇原创文章

    阅读本文大概需要8分钟

    前面讲了这么多正则表达式的知识,光说不练假把式,我觉得学习正则表达式比较好的方法就是思考,练习,再验证,再思考,下面我们先来一篇实战运用一下

    一. 关于简单的字符串的例子

    1.设计一个正则来过滤一个字符串序列中的10到59

    1).首先我们想到最简单的是patt=r"10|11|12|13...59",但是这样太复杂了,能不能简单一点呢~~有办法的,我们来分解一下:

    首先这个数字是2位数

    数字的都是十几,二十几,三十几,四十几,五十几,所以第一位数在1到5之间,第二位数在0到9之间

    那么改成patt=r"[1-5][0-9]"

    import re

    patt=r'[1-5][0-9]'

    match=re.findall(patt,'10,20,30,40,2,3,59,60')

    if match:

    print match

    >>['10', '20', '30', '40', '59']

    也许有同学不服气,说有啥了不起的,我用推导列表也可以搞定,是的这个你可以写成如下:

    str1='10,20,30,40,2,3,59,60'

    print [x for x in str1.split(',')\

    ifint(x)>=10andint(x)<=59]

    >>['10', '20', '30', '40', '59']

    2).好,我们来改动一下,若把字符串改成下面这样:

    str1='xy,10,20,30,40,62,3,59,1w'

    你这个时候再用列表推导就很难处理了,又有字符,又有数字,又有字符混合数字,怎么办

    写代码要好多if/else,这是时候该正则表达式威猛帅哥出场啦,为啥题目说1个小时的事3分钟搞定有道理的,接着看

    import re

    str1='xy,10,20,30,40,62,3,59,1w'

    patt=r'[1-5][0-9]'

    match=re.findall(patt,'str1')

    if match:

    print match

    >>['10', '20', '30', '40', '59']

    看是不是很简便

    2.过滤字符串中的只含2个字符的字母,并且第一个字母是大写A或B或C

    有了上面的思路,可以顺藤摸瓜,好我们来分析一下

    1).字母我们用[a-zA-Z]来表示,只含2个字母,那就[a-zA-Z][a-zA-Z]

    2).第一个字母必须是大写的A或B或C,那就[ABC][a-zA-Z]

    import re

    patt=r'[A-C][a-zA-Z]'

    match=re.findall(patt,'xy,1,2,3,4,Ab,w1,Cz')

    if match:

    print match

    >>['Ab', 'Cz']

    这招在过滤邮件里面经常用到,若不用正则表达式,启用其他的方法,则很麻烦,虽然也能解决,但是不方便

    3.过滤一个字符串中的含3个字母的独立字符

    比如这样的一个字符串'xy,1,2,?,123@sohu,Ab,w1,Cz,xyh,abc',我们怎么办,分析一下吧:

    1).首先要设计出匹配字母并且是3个字母,我们很容易想到patt=r'[a-zA-Z][a-zA-Z][a-zA-Z]'或者patt=r'[a-zA-Z]{3}'

    import re

    patt=r'[a-zA-Z]{3}'

    match=re.findall(patt,'xyhh,a,1,2,?,123@sohu,Ab,w1,Cz,xyh,abc')

    if match:

    print match

    >>['xyh', 'soh', 'xyh', 'abc']

    2).继续分析

    上面的解决方案虽然解决了一部分的问题,但是很明显结果不完全正确,因为"xyhh","123@sohu"这样的字符组是我们不想要的

    我们真正想要的是'xyh'和'abc',怎么办呢...我们可以这样改:patt=r'\b[a-zA-Z]{3}\b'

    我们加上了"\b"表示匹配单词的边界,这样3个字母就是独立的字符组

    import re

    patt=r'\b[a-zA-Z]{3}\b'

    match=re.findall(patt,'xyhh,a,1,2,?,123@sohu,Ab,w1,Cz,xyh,abc')

    if match:

    print match

    >>

    ['xyh', 'abc']

    4.过滤一个字符串中的含3个字母的字符,并且最后一个字母是z

    跟上面类似,大家思考一下应该很快有答案,有同学说是不是这样就可以了

    import re

    patt=r'[a-zA-Z][a-zA-Z][z]+'

    match=re.findall(patt,'xy,1,2,3,4,Ab,w1,Cz,xyh,xyz,xyzz')

    if match:

    print match

    >>['xyz', 'xyzz']

    不对啊,怎么把'xyzz'弄进来来,大家思考一下为啥'+'不行,或者换成'*'行不行,欢迎留言讨论

    正确的应该加'\b'来框定单词边界

    import re

    patt=r'\b[a-zA-Z][a-zA-Z][z]\b'

    match=re.findall(patt,'xy,1,2,3,4,Ab,w1,Cz,xyh,xyz,xyzz')

    if match:

    print match

    >>['xyz']

    二. 匹配12小时制时间

    一般的12小时的时间比如8:30am或者12:15pm,这样的时间,我们应该如何用正则来匹配过滤呢,大家有没有思路,先思考2分钟,然后再往下看:

    第一步:问题分解,时刻肯定是数字,所以应该是如下的格式

    import re

    patt=r'[0-9][0-9]:[0-9][0-9]am|[0-9][0-9]:[0-9][0-9]pm'

    match=re.findall(patt,'10:00am,99:90am,8:00am,12:49pm,3:51pm,15:00pm')

    ifmatch:

    printmatch

    >>['10:00am', '99:90am', '12:49pm','15:00pm']

    第二步:上面第一步虽然解析出了'10:00am', '12:49pm',but没有过滤掉错误的时间日期'99:90am','15:00pm'更重要的是没有解析出8:00am,3:51pm,因为小时数可以是一位,不一定要两位,而且分钟只能是0-5,怎么破,我们来改动一下吧:

    patt=r'[0-9][0-9]:[0-5][0-9]am|[0-9][0-9]:[0-5][0-9]pm'

    改成patt=r'[0-9][0-9]:[0-5][0-9][ap]m'

    再来仔细看小时数,如果小时数是一个两位数

    1),第一位只能是1,用[1-9]匹配一位数

    2),如果是两位数,那么1[012]匹配两位数

    然后再改成patt=r'1[0-2]|[1-9]:[0-5][0-9][ap]m'#注意看加了一个或'|'

    import re

    patt=r'(1[0-2]|[1-9])(:)([0-5][0-9][ap]m)'

    match=re.findall(patt,'10:00am,99:90am,8:00am,12:49pm,3:51pm,15:00pm')

    if match:

    print [''.join(x)for x in match]

    >>['10:00am', '8:00am', '12:49pm', '3:51pm','5:00pm']

    第三步:经过上面2步已经大功告成了,但是15:00pm被匹配成5:00pm,怎么破,加个单词边界就可以搞定:

    import re

    patt=r'\b(1[0-2]|[1-9])(:)([0-5][0-9][ap]m)'

    match=re.findall(patt,'10:00am,99:90am,8:00am,12:49pm,3:51pm,15:00pm')

    if match:

    print [''.join(x)for x in match]

    >>['10:00am', '8:00am', '12:49pm', '3:51pm']

    结束之前:留一道思考题

    如果24小时制时间比如23:23pm,或者29:19pm(不正确的格式)

    '10:00am,99:90am,8:00am,19:19pm:14:00pm,5:xm,23:23pm,29:19pm'

    如何用正则去匹配 ,欢迎留言提出你的解法

    相关文章

      网友评论

      • HBU_DAVID:题目吸引人,一下就冲进来了。内容讲的深入浅出,例子简单易懂。一直逃避学习re的我,就这样入门并喜欢上了re。感谢!
        菜鸟学python:@HBU_DAVID 感谢支持
      • AlexQian:patt = r'\b(1[0-9]|2[0-3]|[0-9])(:)([0-5][0-9][ap]m)' 我暂时只想到这样做:pensive:
        菜鸟学python:@AlexQian 不错,赞一个
      • 爱学习的菜鸟:觉得是干货满满,获益良多,好好收藏

      本文标题:正则实战秘籍分享-学会了能让1小时的工作变成3分钟

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