zoukankan      html  css  js  c++  java
  • python正则表达式1

    正则表达式

           正则表达式是一个特殊的字符序列,计算机科学的一个概念。通常被用来检索、替换那些符合某个模式(规则)的文本。

           许多程序设计语言都支持利用正则表达式进行字符串操作。在python中需要通过正则表达式对字符串进行匹配的时候,可以使用re模块。re模块使python语言拥有全部的正则表达式功能。

    特点:

    • 灵活性、逻辑性和功能性非常强;
    • 可以迅速地用极其简单的方式达到字符串的复杂控制。

    一、python中的正则表达式

           与大多数编程语言相同,正则表达式里也使用 作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符 ,那么使用编程语言表示的正则表达式里将需要4个反斜杠 :前两个和后两个分别用于编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
    print(re.match('\\','hello'))    #需要使用4个反斜杠来匹配一个 
    

      python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。在python字符串前面添加 r 即可将字符串转换为原生字符串。(r:raw string)

    print(re.match(r'\','hello'))    #使用两个反斜杠即可匹配一个 
    

      一个例子:

    import re
    x='hello\nworld'    #hello
    world
    
    #在正则表达式里,如果想要匹配一个  ,需要使用\\
    #第一个参数就是正则匹配规则
    #第二个参数表示需要匹配的字符串
    
    #m=re.search('\\',x)    match和search
    
    #还可以在字符串前面加r,\就表示
    m=re.search(r'\',x)
    
    #search和match方法的执行结果是一个Match类型的对象
    print(m)   #<re.Match object; span=(5, 6), match='\'>
    

      

    二、查找方法的使用

           在python中的查找匹配方法,常见的有下面四种,它们的用法大致相同,但是匹配出的结果却不同。
    • match方法(只匹配字符串开头)
    • search方法(扫描整个字符串,找到第一个匹配)

    • findall方法(扫描整个字符串,找到所有的匹配)
    • finditer方法(扫描整个字符串,找到所有的匹配,并返回要给可迭代对象)

           1、match方法的使用

           re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None。

    re.match(pattern,string,flags=0)
    

      

    参数
    描述
    pattern
    匹配的正则表达式
    string
    要匹配的字符串
    flags
    标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。

           使用group(num)函数来获取匹配表达式

    import re
    result1=re.match(r'He','Hello')
    result2=re.match(r'e','Hello')
    print(result1.group(0))    # 'He'  匹配到的元素
    print(result1.span())    # (0, 2)  匹配元素的位置,从0位到1位,2不包括内
    print(result2)    #  None  没匹配到
    

      2、search方法的使用

           re.search扫描整个字符串并返回第一个成功的匹配
    re.search(pattern,string,flags=0)
    

      应用:

    import re
    result1=re.search(r'he','hello')
    result2=re.search(r'lo','hello')
    print(result1.group(0))     #he
    print(result1.span())      #(0,2)
    print(result2.group(0))     #lo
    print(result2.span())      #(3,5)   不包括第5位
    

      re.match与re.search的区别

           re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
    import re
    result1=re.search(r'天气','今天天气真好!')
    result2=re.match(r'天气','今天天气真好!')
    print(result1)    #  <re.Match object; span=(2, 4), match='天气'>
    print(result2)    #  None
    

      3、findall方法的使用

           在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

           注意:match和search是匹配一次,findall匹配所有。
    re.findall(pattern,string,flags=0)
    

      应用:

    ret=re.findall(r'd+','h12ab34')
    print(ret)      #['12', '34']
    ret=re.match(r'd+','h12ab34')
    print(ret)      #None     match只匹配开头,所以没匹配到
    ret=re.search(r'd+','h12ab34')
    print(ret)      #<re.Match object; span=(0, 2), match='12'>   只匹配一次
    

      4、finditer方法的使用

            和findall类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

    from collections.abc import Iterable
    mm=re.finditer(r'c','agcegcklclexce9')
    print(isinstance(mm, Iterable))    #True
    for m in mm:
        print(m)     
    #<re.Match object; span=(2, 3), match='c'>
    #<re.Match object; span=(5, 6), match='c'>
    #<re.Match object; span=(8, 9), match='c'>
    #<re.Match object; span=(12, 13), match='c'>
    for m in mm:
        print(m.group(),m.span())   #匹配对象里的group保存了匹配的结果
    #c (2, 3)
    #c (5, 6)
    #c (8, 9)
    #c (12, 13)
    

      5、fullmatch方法的使用

            完全匹配
    m4=re.fullmatch(r'he','hello')  #None
    m4=re.fullmatch(r'hello','hello')  #<re.Match object; span=(0, 5), match='hello'>
    

      

     三、re.match类

           当我们调用re.match方法、re.search方法,或者对re.finditer方法的结果进行迭代时,结果是re.Match对象。

    x=re.match(r'h','hello')
    #<re.Match object; span=(0, 1), match='h'>
    y=re.search(r'e','hello')
    z=re.finditer(r'l','hello')
    print(type(x))   #<class 're.Match'>
    print(type(y))   #<class 're.Match'>
    for a in z:
        print(type(a))   #<class 're.Match'>
    

      

           这个类里定义了相关的属性,可以直接使用。

    属性和方法
    说明
    pos
    搜索的开始位置
    endpos
    搜索额结束位置
    string
    搜索的字符串
    re
    当前使用的正则表达式的对象
    lastindex
    最后匹配的组索引
    lastgroup
    最后匹配的组名
    group(index=0)
    某个分组的匹配结果,如index=0,便是匹配整个正则表达式
    group()
    所有分组的匹配结果,每个分组的结果组成一个列表返回
    groupdict()
    返回组名作为key,每个分组的匹配结果作为value的字典
    start([group])
    获取组的开始位置
    end([group])
    获取组的结束位置
    span([group])
    获取组的开始和结束位置
    expand(template)
    使用组的匹配接过来替换模板template中的内容,并把替换后的字符串返回
     
    import re
    ret=re.search(r'm.*a','odabdmjadasdef')
    print(ret.pos,ret.endpos)  #搜索开始和结束的位置,默认是0和字符串长度
    print(ret.group())  #mjada  贪婪模式
    print(ret.group(0))  #mjada
    print(ret.group(1))   #报错,no such group
    #1、在正则表达式里使用()表示一个分组
    #2、如果没有分组,默认只有一组
    #3、分组的下标从0开始
    
    mm=re.search(r'(9.*)(0.*)(5.*7)','fd9dfeca0egfdl5juipxn7xbzi')
    print(mm.group(0))   #第0组就是把整个正则表达式当做一个整体  9dfeca0egfdl5juipxn7
    print(mm.group())   #默认就是第0组
    print(mm.group(1)   #第一个()里对应的    9dfeca
    print(mm.groups())   #('9dfeca', '0egfdl', '5juipxn7')
    
    #?P<name>表达式    可以给分组起名
    mmm=re.search(r'(9.*)(?<middle>0.*)(5.*7)','fd9dfeca0egfdl5juipxn7xbzi')
    print(mmm.groupdict())    #{'middle': '0egfdl'}
    print(mmm.group('middle'))   #0egfdl            通过分组名获取到分组里匹配的字符串
    print(mmm.span(1))  #(2, 8)   获取第一个分组的起始位置和结束位置,包前不包后
    

     

    四、re.compile方法的使用

           在使用正则表达式时,可以直接调用re模块的match,search,findall等方法,传入指定的正则表达式。同时,也可以调用re.compile方法,生成一个正则表达式对象,再调用这个正则表达式对象的相关方法实现匹配。
    import re
    ret=re.search(r'm.*a','odabdmjadasdef')
    print(ret)     #<re.Match object; span=(5, 10), match='mjada'>
    
    r=re.compile(r'm.*a')
    s=r.search('odabdmjadasdef')
    print(s)       #<re.Match object; span=(5, 10), match='mjada'>
    

      在python里面,在大多数情况下真的不需要使用re.compile!

           在re里的match、search、fullmatch等方法里,都返回_compile()

            在re里的compile方法里,同样返回_compile()

           我们常用的正则表达式方法,都已经自带compile了!根本没有必要多此一举re.compile再调用正则表达式方法。

           而_compile()方法的源代码里自带缓存。它会自动储存最多512条由type(pattern), pattern, flags)组成的Key,只要是同一个正则表达式,同一个flag,那么调用两次_compile时,第二次会直接读取缓存。

            所以,再大多数情况下不需要手动调用re.compile,除非你的项目涉及到几百万以上的正则表达式查询。

  • 相关阅读:
    Android Studio 或 IntelliJ IDEA获取数字签名的方法
    android四大组件学习总结以及各个组件示例(2)
    android四大组件学习总结以及各个组件示例(1)
    Android利用canvas画画板
    Android service 服务的应用之电话监听器以及短信监听器
    Android Gesture 手势创建以及使用示例
    安卓http源码查看器详解
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    二叉树的非递归遍历(栈)
    python 游戏(滑动拼图Slide_Puzzle)
  • 原文地址:https://www.cnblogs.com/shixiaoxun/p/14528619.html
Copyright © 2011-2022 走看看