美文网首页
python正则表达式

python正则表达式

作者: Dxes | 来源:发表于2019-11-27 19:40 被阅读0次
    1.内存管理基础(C)

    内存分为栈区间和堆区间,栈区间的内容是系统自动申请自动释放;堆上的内存需要程序通过malloc函数去申请,通过调用free函数去释放;
    高级语言(java\c++\OC\Python)中的内存管理机制,都是针对堆上的内存的管理进行的自动化操作

    2.Python的内存管理机制

    1)内存的申请
    python中的所有数据都是存在堆中的,变量是保存在栈区间的,变量中保存的保存在堆中的数据的地址。
    重新给变量赋值,会先在内存中开辟新的内存空间保存新的数据,然后将新的数据的地址重新保存到变量
    但如果使用数字或者字符串给变量赋值,不会直接开辟新的内存,而是先检查内存有没有这个数据,如果有,直接将原来的数据的地址给变量

    2)内存的释放(垃圾回收机制)
    在python中一个数据对应的内存空间是否释放,就看这个数据的引用计数是否为0;如果引用计数为0,数据对应的内存就会自动被释放
    循环引用问题:python的垃圾回收机制会自动处理循环引用问题
    增加引用计数:增加数据的引用(让更多的变量来保存数据的地址)
    减少引用计数:删除引用,或者让引用去保存新的数据

    from sys import getrefcount
    print('======================内存申请====================')
    a = 10
    print(id(a))
    a = 100
    print(id(a))
    
    b = []
    print(id(b))     # 4495144200
    b = []
    print(id(b))     # 4495187272
    
    c = {'a': 10}
    print(id(c))     # 4493576304
    c = {'a': 10}
    print(id(c))     # 4493576376
    
    d = 100
    print(id(d))   # 4491424800
    d = 100
    print(id(d))   # 4491424800
    
    e = 'abc'
    print(id(e))   # 4484038984
    e = 'abc'
    print(id(e))   # 4484038984
    
    print('=========================内存释放======================')
    list1 = [1, 2, 3]    # re: 1
    print(getrefcount(list1))  # 2
    
    list2 = list1
    print(getrefcount(list1))   # 3
    
    dict1 = {'a': list1}
    print(getrefcount(list1), getrefcount(list2))   # 4
    
    del list1
    print(getrefcount(list2))    # 3
    
    dict1['a'] = 'abc'
    print(getrefcount(list2))    # 2
    
    
    # 循环引用
    list1 = [1, 2, 3]
    list2 = [list1, 10, 20]
    list1.append(list2)
    
    del list1
    del list2
    
    
    class Person:
        pass
    
    
    Person()
    
    list3 = [[100, 200], 20, 30, 40]
    # del list3[0]
    list3.pop(0)
    
    
    num = 6
    print(getrefcount(num))
    

    拷贝
    from copy import copy, deepcopy
    
    
    class Dog:
        def __init__(self, name, color='黄色'):
            self.name = name
            self.color = color
    
        def __repr__(self):
            return '<%s __id: %s>' % (str(self.__dict__)[1:-1], id(self))
    
    
    class Person:
        def __init__(self, name, age=10, gender='男', dog=None):
            self.name = name
            self.age = age
            self.gender = gender
            self.dog = dog
    
        # 这个函数会在打印当前类的对象的时候自动调用; 函数的返回值就是打印的结果
        # 返回值是字符串
        def __repr__(self):
            return '<%s __id: %s>' % (str(self.__dict__)[1:-1], id(self))
    
    1.直接赋值

    用一个变量直接给另外一个变量赋值的时候赋的是地址;赋值后两个变量保存的是同一个数据的地址

    print('直接赋值')
    p1 = Person('小明',dog = Dog('大黄'))
    p2 =  p1   # 赋值后p1和p2指向是同一个Person对象
    print('p1:', p1)
    print('p2:', p2)
    p1.gender = '女'
    p1.dog.color = '白色'
    print('p1:', p1)
    print('p2:', p2)
    
    2.浅拷贝

    复制原数据产生一个新的数据(值和原数据一样,地址不同),然后将新的数据的地址返回;如果有子对象,子对象不会复制

    print('=============浅拷贝==============')
    p1 = Person('小明', dog=Dog('大黄'))
    p2 = copy(p1)
    print(p1)
    print(p2)
    p1.gender = '女'
    p1.dog.color = '白色'
    print('p1:', p1)
    print('p2:', p2)
    
    3.深拷贝

    复制原数据产生一个新的数据(值和原数据一样,地址不同),然后将新的数据的地址返回;如果有子对象,子对象也会复制

    print("========深拷贝=========")
    p1 = Person('小花',dog = Dog('大黄'))
    p2 = deepcopy(p1)
    print('p1:', p1)
    print('p2:', p2)
    p1.gender = '女'
    p1.dog.color = '白色'
    print('p1:', p1)
    print('p2:', p2)
    

    1.什么是正则表达式

    用正则符号来描述字符串规则让字符串匹配更简单的一种工具;正则本身的语法和语言无关,几乎所有的编程语言都支持正则
    python通过提供的re模块来支持正则表达式

    匹配符号

    1)普通字符 - 在正则表达式中没有特殊功能或者特殊意义的字符都是普通字符
    普通字符在正则表达是中就代表这个符号本身,匹配的时候只能和这个指定的字符进行匹配

    re_str = r'abc'
    result = re.fullmatch(re_str,'abc')
    print(result)
    
    
    2) . -代表任意一个字符
    re_str = r'a.b'   # 匹配一个长度是3的字符串,第一个字符是a,最后一个字符是b, 中间是任意字符
    print(re.fullmatch(re_str, 'abc'))   # None
    print(re.fullmatch(re_str, 'a你b'))
    
    print(re.fullmatch(r'a..b', 'au9b'))
    
    3) \w -ASCII码表中只能匹配字母、数字或者下划线;ASCII码表以外的都可以匹配,一个\w只能匹配一个字符
    re_str = r'a\wb'
    print(re.fullmatch(re_str, 'awb'))
    print(re.fullmatch(re_str, 'a8b'))
    print(re.fullmatch(re_str, 'a_b'))
    print(re.fullmatch(re_str, 'a+b'))   # None
    print(re.fullmatch(re_str, 'a胡b'))
    
    4) \d - 匹配任意一个数字字符
    re_str = r'a\d\db'
    print(re.fullmatch(re_str, 'a23b'))
    print(re.fullmatch(re_str, 'a33b'))
    print(re.fullmatch(re_str, 'aa3b'))   # None
    
    5)\s - 匹配任意一个空白字符
    re_str = r'a\sb'
    print(re.fullmatch(re_str, 'a b'))
    print(re.fullmatch(re_str, 'a\tb'))
    print(re.fullmatch(re_str, 'a\nb'))
    print(re.fullmatch(re_str, 'a   b'))   # None
    
    6)\W,\D,\S,---->与小写的\w,\d,\s功能完全相反
    # \D - 匹配任意非数字字符
    print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb=c+d'))
    print(re.fullmatch(r'a\Db\Sc\Wd', 'a2b=c+d'))   # None
    print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb c+d'))   # None
    print(re.fullmatch(r'a\Db\Sc\Wd', 'aZb=c胡d'))   # None
    
    7) [字符集] - 匹配字符集中的任意一个字符

    注意:一个[]只能匹配一个字符
    a.[普通字符集] 例如:[abc] - 匹配a,b,c 三个字符中的任意一个
    [aA123] - 匹配a,A,1,2,3中任意一个
    b.[字符1-字符2] 例如:[1-9] - 匹配123456789中的任意一个字符
    [0-9] ->\d
    [a-z] ->匹配任何一个小写字母
    [A-Z] ->匹配任何一个大写字母
    [a-zA-Z] ->匹配任何一个字母
    [\u4e00-\u9fa5] - 匹配任意一个中文字符
    [1-9abc] - 匹配1~9或者abc中的任意一个字符
    [a-zA-Z0-9_] - 匹配字母数字下划线
    [\dxyz] - 任意数字或者x、y、z
    注意: 字符1的编码值必须小于字符2的编码值

    print(re.fullmatch(r'a[xyz89?]b', 'azb'))
    print(re.fullmatch(r'a[xyz]b', 'anb'))
    print(re.fullmatch(r'a[23456789]b', r'a7b'))
    print(re.fullmatch(r'a[1-9abc]b', 'aab'))
    print(re.fullmatch(r'a[abc1-9]b', 'aab'))
    print(re.fullmatch(r'a[ac1-9b]b', 'aab'))
    print(re.fullmatch(r'a[+*-]b', 'a-b'))
    print(re.fullmatch(r'a[\dxyz]b', 'axb'))
    print(re.fullmatch(r'a[\\dxyz]b', 'a\\b'))
    
    8)[^字符集] -> 匹配除了字符集以外的任意一个字符
    """
    [^abc]  - 匹配除了abc以外的任意一个字符
    [^1-9]  - 匹配除了1~9以外的任意一个字符
    """
    print(re.fullmatch(r'a[^xyz]b', 'a=b'))   # None
    print(re.fullmatch(r'a[xyz^]b', 'a^b'))
    
    检测符号
    # 1) \b  - 检测是否是单词结尾
    """
    单词结尾 - 所有可以区分出两个不同单词的符号都是单词结尾,其中字符串开头和字符串结尾
    用法: 检测\b所在的位置是否是单词结尾;不影响匹配的时候的字符串长度
    """
    # 匹配一个长度是3的字符串,第一个字符是a,最后一个字符是b,中间是任意一个数字;并且要求b的后面是单词边界
    re_str = r'a\db\b'
    print(re.fullmatch(re_str, 'a7b'))
    
    re_str = r'a\bxy'
    print(re.fullmatch(re_str, 'a xy'))   # None
    
    re_str = r'abc\b\sxyz'
    print(re.fullmatch(re_str, 'abc xyz'))
    
    result = re.search(r'\d\d\d\b', 'ashdjfhow2378how 899kah989sf 789')
    print(result)
    
    # 2)^ - 检测字符串开头
    # 判断^所在的位置是否是字符串开头
    re_str = r'^\d\d\d'
    print(re.fullmatch(re_str, '123'))
    print(re.search(re_str, 'k898ahs237khhj'))
    
    # 3)$ - 检测字符串结尾
    re_str = r'\d\d\d$'
    print(re.search(re_str, '123k898ahs237khhj990'))
    
    匹配次数
    # 1) ?  - 匹配0次或1次
    """
    x?   -  x出现0次或1次
    \d?  -  任意数字出现0次或1次
    [a-z]?  - 小写字母出现0次或1次
    """
    re_str = r'ax?b'
    print(re.fullmatch(re_str, 'ab'))
    print(re.fullmatch(re_str, 'axb'))
    print(re.fullmatch(re_str, 'axxb'))   # None
    
    # 2) *  - 匹配0次或多次
    re_str = r'a\d*b'   # r'a\d\d...\d\db'
    print(re.fullmatch(re_str, 'ab'))
    print(re.fullmatch(re_str, 'a2b'))
    print(re.fullmatch(re_str, 'a12b'))
    print(re.fullmatch(re_str, 'a1272937928329b'))
    
    # 3) +  - 匹配1次或多次
    re_str = r'a\d+b'
    print(re.fullmatch(re_str, 'ac'))   # None
    print(re.fullmatch(re_str, 'a2b'))
    print(re.fullmatch(re_str, 'a12b'))
    print(re.fullmatch(re_str, 'a1272937928329b'))
    
    # 4){}
    """
    {N}  -  匹配N次
    {M,N} - 匹配M到N次:  ? -> {0,1}
    {M,}  - 匹配至少M次  * -> {0,}   + -> {1,}
    {,N}  - 匹配最多N次
    """
    re_str = r'a\d{5}b'
    print(re.fullmatch(re_str, 'a78988b'))
    print(re.fullmatch(re_str, 'a7898b'))   # None
    print(re.fullmatch(re_str, 'a789880b'))  # None
    
    re_str = r'a\d{3,5}b'
    print(re.fullmatch(re_str, 'a78988b'))
    print(re.fullmatch(re_str, 'a7898b'))
    print(re.fullmatch(re_str, 'a789880b'))   # None
    
    # 练习: 写一个正则表达式判断输入的内容是否是整数
    # 123 -> 成功!  123a -> 失败!   -123  -> 成功!   --123 -> 失败!   +123 -> 成功
    re_str = r'[+-]?[1-9]\d*'
    

    ---贪婪和非贪婪

    """
    匹配次数不确定的时候有贪婪和非贪婪两种状态
    ?、*、+、{M,N}, {M,}, {,N}  -  默认是贪婪的
    ??, *?, +?, {M,N}?, {M,}?, {,N}?   -  非贪婪
    
    贪婪 - 在能匹配成功的前提下,尽可能多的匹配
    非贪婪 - 在能匹配成功的前提下,尽可能少的匹配
    
    """
    re_str = r'\d{3,5}'
    print(re.search(re_str, 'abc2732939333===='))  # match='27329'
    re_str = r'\d{3,5}?'
    print(re.search(re_str, 'abc2732939333===='))  # match='273'
    re_str = r'a\d{3,5}?b'
    print(re.search(re_str, 'a7283b238kk===='))   # match='a7283b'
    
    
    re_str = r'\d+'
    print(re.search(re_str, 'abc2732939333===='))  # match='2732939333'
    
    
    re_str = r'a.+b'
    print(re.search(re_str, '==a12xb67yusb0293==='))  # match='a12xb67yusb'
    
    re_str = r'a.+?b'
    print(re.search(re_str, '==a12xb67yusb0293==='))  # match='a12xb'
    
    分之和分组
    # 1) |  -  分之
    """
    正则1|正则2  - 先让正则1去匹配,如果匹配再用正则2匹配;只要两个中有一个能够匹配成功就成功
    """
    # 匹配三个数字或者三个字母的字符串
    re_str = r'\d{3}|[a-zA-Z]{3}'
    print(re.fullmatch(re_str, '890'))
    
    # 匹配一个字符串: abc前是3个数字或者3个字母
    # 123abc, uJhabc
    re_str = r'\d{3}abc|[a-zA-Z]{3}abc'
    
    
    # 2) ()  - 分组
    """
    (正则表达式)  - 将正则表达式看成一个整体进行操作
    整体控制次数: ()匹配次数
    重复:  带分组的正则表达式\M  --  在\M的位置重前面第M个分组匹配到的内容
    """
    # ab78hj90lo23
    re_str = r'[a-z]{2}\d{2}[a-z]{2}\d{2}[a-z]{2}\d{2}'
    
    # 9h8k9j8j7h6u5k....
    re_str = r'(\d[a-z])+'
    
    # 匹配一个字符串: abc前是3个数字或者3个字母
    re_str = r'(\d{3}|[a-z]{3})abc'
    print(re.fullmatch(re_str, 'mskabc'))
    
    # abc123abc -成功!  xab234xab  - 成功!  xyz123xyz -成功!
    # abc123acb -失败!   xab234sdk  -失败!
    # ab-ab   abc-abc   123-123
    
    re_str = r'(\d+)abc\1'
    print(re.fullmatch(re_str, '234abc234'))
    print(re.fullmatch(re_str, '12345abc12345'))
    print(re.fullmatch(re_str, '234abc890'))   # None
    
    re_str = r'(\d+)([a-z]+)=\2'
    print(re.fullmatch(re_str, '6kh=kh'))
    
    re_str = r'(\d+)=\1([a-z]+)'
    print(re.fullmatch(re_str, '123=123ioo'))
    
    re_str = r'(\d{3})=(\1){2}'
    print(re.fullmatch(re_str, '234=234234'))
    

    相关文章

      网友评论

          本文标题:python正则表达式

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