菜鸟学习Python(第十期)~~正则表达式(三)

作者: KangSmit的算法那些事儿 | 来源:发表于2019-10-03 21:32 被阅读0次

    继续上一次正则表达式学习~~
    点击下面蓝色字体可回看往期知识点:

    Python(第十期)~~正则表达式(一)
    Python(第十期)~~正则表达式(二)

    回顾:
    正则表达式是以字符串的形式来描述的,而且表达式的强大之处在于特殊符号的应用。

    值得关注的是,点号(.)在正则表达式中表示匹配时除了 换行符之外的任何字符,它就是一个特殊的字符。正是这些特殊符号,使得一个正则表达式可以匹配一个复杂的规则,而不仅仅是匹配一个字符串。特别地,如果你只需要匹配一个字符串,那用 find() 方法就可以了。

    由于特殊符号 前面已经提到过,因此这里就自行去查看:

    Python3.x 正则表达式部分特殊符号及用法(详解)

    下面引入特殊字符:
    特殊符号是由两部分组成的,一部分是 元字符。此外,所有的元字符包括:

    . ^ $ * + ? { } [ ] \ | ( )

    而另一部分则则是 反斜杠 \ 加上普通符号 * 组成的特殊符号,它拥有特殊的含义。

    13、元字符

    (1)、点号(.):除了换行符之外的任何字符都基本可以匹配。
    (2)、竖线 | :类似逻辑关系中的或,学过C语言的同学们都知道,这就是按位或的意思。例如,A|B就 表示匹配正则表达式 A或者B的形式。

    >>> import re
    >>> re.search(r"Love(E|F)", "LoveE")
    <re.Match object; span=(0, 5), match='LoveE'>
    >>> re.search(r"Love(L|O)","I Love YOU")
    >>> re.search(r"Love(L|O)","I LoveL YOU")
    <re.Match object; span=(2, 7), match='LoveL'>
    >>> re.search(r"Love(e|O)","I Love YOU")
    >>> re.search(r"Lov(e|O)","I Love YOU")
    <re.Match object; span=(2, 6), match='Love'>
    

    (3)、托字符(^):定位匹配,匹配字符串的开始位置(即确定一个位置)。

    >>> re.search(r"^love", "love you, Python")
    <re.Match object; span=(0, 4), match='love'>
    >>> re.search(r"^日本", "日本 you, Python")
    <re.Match object; span=(0, 2), match='日本'>
    >>> re.search(r"^2019", "2019的欧洲, LOVE")
    <re.Match object; span=(0, 4), match='2019'>
    >>> re.search(r"^2", "2019的欧洲, LOVE")
    <re.Match object; span=(0, 1), match='2'>
    >>> re.search(r"^2019的欧洲", "2019的欧洲, LOVE")
    <re.Match object; span=(0, 7), match='2019的欧洲'>
    

    (4)、美元符号($):匹配输入字符串的结束位置

    >>> re.search(r"LOVE$", "2019的欧洲, LOVE")
    <re.Match object; span=(9, 13), match='LOVE'>
    >>> re.search(r"2019的欧洲$", "love, 2019的欧洲")
    <re.Match object; span=(6, 13), match='2019的欧洲'>
    

    (5)、反斜杠 \ (再细说用法)
    接下来的元字符是最困难、最复杂的 反斜杠(),反斜杠在正则表达式中应用是最广泛的,它既可以将一个普通的字符变为特殊字符(这部分内容下节课继续讲解),也可以解除元字符的特殊功能,这些在前面已经提到过。

    特别地 . 匹配的就不是除换行符之外的任何字符了,他匹配的就是一个点(.)。

    如果在反斜杠 \ 后面加的是数字,那么有两种表示方案:
    ①、如果跟着的数字是 1~99,就表示引用序号对应的值组所匹配的字符串,其中序号所对应的值组:为 \ 前面的值组,\ 序号必须在对应的值组的正后面,序号为第几个值组。 为了方便理解请看下面的例子:

    >>> re.search(r"(you)\1", "I love youyou")
    <re.Match object; span=(7, 13), match='youyou'>
    >>> re.search(r"(欧洲)\1", "you from 欧洲欧洲")
    <re.Match object; span=(9, 13), match='欧洲欧洲'>
    >>> re.search(r"(love)\1(you)", "I loveloveyouyou")
    <re.Match object; span=(2, 13), match='loveloveyou'>
    >>> re.search(r"(love)(you)\2", "I loveloveyouyou")
    <re.Match object; span=(6, 16), match='loveyouyou'>
    >>> re.search(r"(love)\1(you)\2", "I loveloveyouyou")
    <re.Match object; span=(2, 16), match='loveloveyouyou'>
    >>> re.search(r"(欧洲)\1(英国)\2", "二战时期的 欧洲欧洲英国英国")
    <re.Match object; span=(6, 14), match='欧洲欧洲英国英国'>
    

    源码剖析:
    上面的(you)是第一个值组(序号是从1开始计算的,因为0表示一个八进制数),所以 \1,且\1 表示you,其实 r’(you)\1’ 就等于 ‘youyou’。

    其中值组就是用小括号括起来的一个整体,与数学中的括号是一样的,把一个东西当做一个整体,那么就把它括起来。

    >>> re.search(r"(I )love(英国)\2", "I love英国英国.com")
    <re.Match object; span=(0, 10), match='I love英国英国'>
    >>> re.search(r"(you )love(英国)\2", "you love英国英国.com")
    <re.Match object; span=(0, 12), match='you love英国英国'>
    >>> re.search(r"(you )love(英国)\2", "you love英国英国")
    <re.Match object; span=(0, 12), match='you love英国英国'>
    >>> re.search(r"(I )love(you)\2", "I loveyouyou.com")
    <re.Match object; span=(0, 12), match='I loveyouyou'>
    

    ②、如果随后紧跟的数字是 0 或者 3位的数字,那么它是一个八进制数,表示的是这个八进制数对应的 的是ASCII 码对应的字符

    回顾一下进制转换的数学逻辑:

    (a)


    (b)


    (c)


    例如:字符 0 对应的十进制数为 48,对应的八进制数为 60,这里要三位数,就是060

    所以:

    >>> import re
    >>> re.search(r"\060", '0')
    <re.Match object; span=(0, 1), match='0'>
    >>> re.search(r"I love love\060", 'I love love0')
    <re.Match object; span=(0, 12), match='I love love0'>
    

    (6)、中括号([ ]),作用是生成一个字符类。
    其实字符类就是一个字符集合的意思,此外,值的注意的是:被中括号包含在里面的元字符都会失去特殊功能,这与就反斜杠加上一个元字符是类似的,举例:

    >>> import re
    >>> re.search(r"[.]", 'I love you.com')
    <re.Match object; span=(10, 11), match='.'>
    >>> re.search(r"[u.]", 'I love you.com')
    <re.Match object; span=(9, 10), match='u'>
    >>> re.search(r"[.u]", 'I love you.com')
    <re.Match object; span=(9, 10), match='u'>
    

    字符类的意思就是将自身里面的内容都当做普通的字符看待,除了几个特殊的字符:
    比如:
    ①、小横杠(-),我们用它表示范围,在前面讲过,此次讲一讲其他方法:re.findall(),在Python解释器中按F1打开文档


    大致含义:
    对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。
    (也可访问线上中文文档:https://docs.python.org/zh-cn/3/library/re.html?highlight=findall#re.findall

    在 3.7 版更改: 非空匹配现在可以在前一个空匹配之后出现了。
    特别地,findall 和 search 相比,似乎更符合我们的需求,但是当遇到值组时,findall 也会有陷阱,后期会升入补充这部分知识点。

    ②、反斜杠( \ ),把反斜杠放在字符类[ ]中,它不表示本身,因为这样会报错, 反斜杠在字符类里,表示的是Python 字符串的转义符。

    在字符串里,我们都知道 \n 表示回车换行的意思,由此我们有:

    >>> re.findall(r"[\n]","12a32\nbc43jf3")
    ['\n']
    >>> re.findall(r"[\n]","12a3\nbc243jf3")
    ['\n']
    >>> re.findall(r"[\n]","12a3 \n bc243jf3")
    ['\n']
    

    ③托字符 ^,在字符类[ ]里,表示‘除了’(取反)的意思,但是要注意的是,这个托字符 ^ 必须放在最前面:

    >>> re.findall(r"[^a-z]","250e1314bc1997fh2019")
    ['2', '5', '0', '1', '3', '1', '4', '1', '9', '9', '7', '2', '0', '1', '9']
    

    如果放在后面,就是表示匹配它本身了。

    特别地,这里说明一种元字符重复元字符,大括号{ },如{i,j}(要求i,j均为非负整数,且i<=j)表示前面的内容匹配 i~j次。

    >>> re.search(r'Pythox{3}', 'I love Pythoxxx')
    <_sre.SRE_Match object; span=(7, 15), match='Pythoxxx'>
    >>> re.search(r'(you){3}', 'I love youyouyou')
    <re.Match object; span=(7, 16), match='youyouyou'>
    
    每日三道题, 笔试不吃亏

    题目10:古典问题(斐波拉契数列):
    有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    x1 = 1
    x2 = 1
    for i in range(1,22):
        print('%12ld %12ld' % (x1,x2))
        if (i % 3) == 0:
            print(end='')
        x1 = x1 + x2
        x2 = x1 + x2
    

    执行结果:

    题目11:判断101-200之间有多少个素数,并输出所有素数。
    程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。

    h = 0
    leap = 1
    from math import sqrt
    from sys import stdout
    for m in range(520,1314):
        k = int(sqrt(m + 1))
        for i in range(2,k + 1):
            if m % i == 0:
                leap = 0
                break
        if leap == 1:
            print(end='%-4d' % m)
            h += 1
            if h % 10 == 0:
                print(end='')
        leap = 1
    print('素数个数为%d个' % h)
    

    执行结果:

    题目12:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个"水仙花数",并且153=1 ^3 + 5^3 + 3^3。

    M = ""
    for a in range(1,10):
        for b in range(10):
            for c in range(10):
                num = a*100+b*10+c
                if a**3+b**3+c**3 == num:
                    print(M,end='')
                    print(num,end=' ')
                    M=","
    

    执行结果:

    153 ,370 ,371 ,407 
    

    或者

    for i in range(100,1000):
        s=str(i)
        one=int(s[-1])
        ten=int(s[-2])
        hun=int(s[-3])
        if i == one**3+ten**3+hun**3:
            print(i)
    

    执行结果:

    扫码关注我,一起交流学习

    相关文章

      网友评论

        本文标题:菜鸟学习Python(第十期)~~正则表达式(三)

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