• 正则表达式 re模块


    在介绍正则表达式和re模块之前,先简要介绍一下

    正则表达式与re模块的关系
      1.正则表达式是一门独立的技术,任何语言均可使用
      2.python中要想使用正则表达式需要通过re模块

    正则表达式

    元字符

    ##############################################

     

    分组

    ##############################################

     

    量词

    ##############################################

     

    • {n}代表大括号前字符n个
    • {n,m}代表大括号前字符n-m个
    • {n,}代表大括号前字符n-多个
    • {+,}代表大括号前字符1-多个
    • {0,}代表大括号前字符0-多个

    量词只能限制紧挨着他的那一个正则符号

    注意:量词需要写在匹配符号的后面,并且只约束紧挨着它的那个正则表达式

     

    转义符

    在正则表达式中,有很多有特殊意义的是元字符,比如 和s等,如果要在正则中匹配正常的" "而不是"换行符"就需要对""进行转义,变成'\'。

    在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中也有特殊的含义,本身还需要转义。所以如果匹配一次" ",字符串中要写成'\n',那么正则里就要写成"\\n",这样就太麻烦了。这个时候我们就用到了r' '这个概念,此时的正则是r'\n'就可以了。

    对照表

     

    语法

    意义

    说明

    "."

    任意字符

     

    "^"

    字符串开始

    '^hello'匹配'helloworld'而不匹配'aaaahellobbb'

    "$"

    字符串结尾

    与上同理

    "*"

    0 个或多个字符(贪婪匹配)

    <*>匹配< itle>chinaunix</title>

    "+"

    1 个或多个字符(贪婪匹配)

    与上同理

    "?"

    0 个或多个字符(贪婪匹配)

    与上同理

    *?,+?,??

    以上三个取第一个匹配结果(非贪婪匹配)

    <*>匹配< itle>

    {m,n}

    对于前一个字符重复mn次,{m}亦可

    a{6}匹配6aa{2,4}匹配24a

    {m,n}?

    对于前一个字符重复mn次,并取尽可能少

    aaaaaa’中a{2,4}只会匹配2

    ""

    特殊字符转义或者特殊序列

     

    []

    表示一个字符集

    [0-9]、[a-z]、[A-Z]、[^0]

    "|"

    A|B,或运算

    (...)

    匹配括号中任意表达式

     

    (?#...)

    注释,可忽略

     

    (?=...)

    Matches if ... matches next, but doesn't consume the string.

    '(?=test)' hellotest中匹配hello

    (?!...)

    Matches if ... doesn't match next.

    '(?!=test)' hello后面不为test,匹配hello

    (?<=...)

    Matches if preceded by ... (must be fixed length).

    '(?<=hello)test' hellotest中匹配test

    (?<!...)

    Matches if not preceded by ... (must be fixed length).

    '(?<!hello)test' hellotest中不匹配test

      

    贪婪匹配

    正则匹配的时候默认都是贪婪匹配(尽量匹配多的)

    <.*>:先拿着里面的.*去匹配所有的内容,然后再根据>往回退着找,遇到即停止
    <.*?>:先拿着?后面的>去匹配符合条件的最少的内容,然后把匹配的结果返回

    你可以通过在量词后面加一个?就可以将贪婪匹配变成惰性匹配

    .*?x
    就是取前面任意长度的字符,直到一个x出现

    Re模块

    三个必须掌握的方法

    re.findall

    # 第一个参数是正则表达式,第二个参数是待匹配的文本内容
    ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
    print(ret)

     

    re.search

    ret = re.search('a', 'eva egon yuan') 
    print(ret.group()) # 结果:'a'
    # 函数会在字符串内查找模式匹配,直到找到第一个匹配然后返回一个包含匹配信息的对象,
    该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None,
    并且需要注意的是如果ret是None,再调用.group()会直接报错。
    这一易错点可以通过if判断来进行筛选
    if ret: print(ret.group())

     

    re.match

    ret = re.match('a', 'abc').group()  # 同search,不过仅在字符串开始处进行匹配
    print(ret)  # ‘a'
    # match是从头开始匹配,如果正则规则从头开始可以匹配上,
    就返回一个对象,需要用group才能显示,如果没匹配上就返回None,调用group()就会报错
    res = re.match('a','eva egon jason')
    print(res)
    print(res.group())
    """
    注意:
        1.match只会匹配字符串的开头部分
        2.当字符串的开头不符合匹配规则的情况下 返回的也是None 调用group也会报错
    """
    
    

     

    search 和match区别要弄清楚!!!!!!!!!!

    match search的区别,mathch从开头开始匹配找一个,search搜索所有找第一个

     

    其他方法

    re.split

    ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
    print(ret)  # ['', '', 'cd'] 返回的还是列表

    re.sub

    ret = re.sub('d', 'H', 'eva3bitten4yuan4',1)  # 将数字替换成'H',参数1表示只替换1个
    # sub('正则表达式','新的内容','待替换的字符串',n)
    """
    先按照正则表达式查找所有符合该表达式的内容 统一替换成'新的内容'  还可以通过n来控制替换的个数
    """
    print(ret)  # eva3bitten4yuan4

    re.subn 

    ret = re.subn('d', 'H', 'eva3bitten4yuan4')  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
    ret1 = re.subn('d', 'H', 'eva3bitten4yuan4',1)  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
    print(ret)  # 返回的是一个元组 元组的第二个元素代表的是替换的个数

    re.compile 

    obj = re.compile('d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
    ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
    res1 = obj.findall('347982734729349827384')
    print(ret.group())  #结果 : 123
    print(res1)  #结果 : ['347', '982', '734', '729', '349', '827', '384']

    re.finditer

    import re
    ret = re.finditer('d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
    print(ret)  # <callable_iterator object at 0x10195f940>
    print(next(ret).group())  #查看第一个结果
    print(next(ret).group())  #查看第二个结果
    print([i.group() for i in ret])  #查看剩余的左右结果

    分组优先机制

    对于search方法

    import re
    res = re.search('^[1-9]d{14}(d{2}[0-9x])?$',110105199812067023)
    print(res.group())
    print(res.group(1))  # 获取正则表达式括号阔起来分组的内容
    print(res.group(2))  # search与match均支持获取分组内容的操作  跟正则无关是python机制

    对于findall方法

    ret = re.findall('www.(baidu|google).com', 'www.google.com')
    print(ret)  # ['google']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    
    ret = re.findall('www.(?:baidu|google).com', 'www.google.com')  # ?:取消分组优先
    print(ret)  # ['www.google.com']

    补充:

    import re
    
    
    ret = re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>")
    #还可以在分组中利用?<name>的形式给分组起名字
    #获取的匹配结果可以直接用group('名字')拿到对应的值
    print(ret.group('tag_name'))  #结果 :h1
    print(ret.group())  #结果 :<h1>hello</h1>
    """
    注意?P=tag_name相当于引用之前正则表达式,并且匹配到的值必须和前面的正则表达式一模一样
    """

    匹配整数:

    ret=re.findall(r"d+","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']
    
    ret=re.findall(r"d+.d*|(d+)","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret) #['1', '2', '60', '', '5', '4', '3']
    ret.remove("")
    print(ret) #['1', '2', '60', '5', '4', '3']

      

  • 相关阅读:
    redis 中 set 和 hset 有什么不同,什么时候使用 hset 什么时候使用set?
    redis的底层数据结构
    python开发-实现redis中的发布订阅功能
    使用redis-py的两个类Redis和StrictRedis时遇到的坑
    python使用redis实现协同控制的分布式锁
    深入理解 Python 异步编程(上)
    linux中read,write和recv,send的区别
    socket常见问题
    python socket 编程之三:长连接、短连接以及心跳
    Flask快速入门
  • 原文地址:https://www.cnblogs.com/PowerTips/p/11199923.html
Copyright © 2020-2023  润新知