第9章 正则表达式

09 正则表达式

9.2 python中的正则表达式
  • re 模块提供的主要函数是search. 它的目的是接受一个正则表达式(针) 和 一个字符串(草堆),并返回发现的第一个匹配(match对象),或者 None

    import re
    
    res = re.search(r"fox", "the quick brown fox jumped...")
    
    print(res)  # <_sre.SRE_Match object; span=(16, 19), match='fox'>
    
    # group() 方法返回一个包含匹配文本的字符串
    print(res.group())
    
    
    
  • 多个匹配

    • re.findall() 返回一个列表

      import re
      
      res = re.findall(r"o", "the quick brown fox jumped...fox")
      
      print(res)  # ['o', 'o', 'o']
      
    • re.finditer() 返回一个生成器

      import re
      
      res = re.finditer(r"o", "the quick brown fox jumped...fox")
      print(res)  # <callable_iterator object at 0x000001EC7D02BDA0>
      
9.3 基本正则表达式
  • 字符组:允许指定一个字符应该与一组可能出现的字符之一,而不仅仅是一个单独字符匹配;可以使用[]并在方括号内累出所有可能的字符从而表示一个字符组

    re.search(r"[Pp]ython", "Python3")
    re.search(r"gr[ae]y", "gray")
    re.search(r"gr[ae]y", "grey")
    
    • 区间

      • [0-9]
      • [a-z][a-zA-Z]
      • [A-Za-z0-9\-_] \代表转义
    • 取反 ^

    • 快捷方式 对应取反快捷方式 \W \D \S \B

      • \w 与任意一个单词字符匹配

      • \d 匹配数字字符

        res = re.search(r"\d", "the quick brown 12fox jumped...fox321")
        print(res)
        res = re.findall(r"\d", "the quick brown 12fox jumped...fox321")
        print(res)
        
      • \s 匹配空白字符, 比如空白、tab、换行

      • \b 匹配一个长度为0 的子串

        res = re.search(r"\bcorn\b", "corn")
        print(res)
        
      • . 匹配任意一个字符(\n 无法匹配)

        res = re.search(r"p....n", "python 3")
        print(res)
        
    • 指定字符串的开始和结束

      # ^ 指定字符串的开始 
      res = re.search(r"^python", "python 3")
      print(res)
      # $ 指定字符串的结尾
      res = re.search(r"python$", "this code is python")
      print(res)
      
  • 可选字符

    • ? 符号指定一个字符、字符组或其他基本单元可选;允许该字符出现零次或一次

      # "honou?r" 允许u 出现或者不出现
      res = re.findall(r"honou?r", "He served with honor and honour")
      print(res)  # ['honor', 'honour']
      
  • 重复

    • 重复次数:{N} 指定一个标记必须重复给定次数,N个字符与标记应该重复的次数对应。

      res = re.search(r"[\d]{3}-[\d]{4}", "867-5309 / Jerry")
      print(res)  # <_sre.SRE_Match object; span=(0, 8), match='867-5309'>
      
    • 重复区间:{M,N} M是下界,N是上界

      # 正则表达式是“贪心”的,尽可能多的匹配字符
      res = re.search(r"[\d]{3,4}", "0421")
      print(res) # <_sre.SRE_Match object; span=(0, 4), match='0421'>
      res = re.search(r"[\d]{3,4}", "042")
      print(res) # <_sre.SRE_Match object; span=(0, 3), match='042'>
      
      # 在重复操作符后加`?`,会导致重复被认为是“惰性”
      res = re.search(r"[\d]{3,4}?", "0421")
      print(res)  # <_sre.SRE_Match object; span=(0, 3), match='042'>
      
    • 开闭区间:{1,}用于指定出现1次或多次,没有上界

      res = re.search(r"[\d]{1,}", "0421")
      print(res)  # <_sre.SRE_Match object; span=(0, 4), match='0421'>
      
  • 速写

    • + 字符代替{1,} (1个或多个); *字符代替{0,}(0个或多个)

      res = re.search(r"[\d]+", "0421")
      print(res) 	#  <_sre.SRE_Match object; span=(0, 4), match='0421'>
      
9.4 分组
  • 使用() 指定分组

  • group() 方法传递一个对应你希望的分组参数(编号默认从1开始)

    • group(0) 零分组 返回一个单独分组
    res = re.search(r"([\d]{3})-([\d]{4})", "867-5309/Jenny")
    print(res.group(1))  # 867
    print(res.groups())  # ('867', '5309')
    print(res.group()) # res.group(0) 867-5309
    
    • 接受任意区间的电话
      • 第一节(\+?1)?[ .-] 寻找任何形式的美国国家号码(+1 1)
      • 第二节\(?[\d]{3})\)?[ .-] 用于抓取区号;可选的连字符或空白
      • 第三节([\d]{3})[ .-]?([\d]{4}) 7为电话号码
    res = re.search(r"(\+?1)?[ .-]?\(?([\d]{3})\)?[ .-]?([\d]{3})[ .-]?([\d]{4})", "(213) 867-5309")
    print(res)
    
  • 命名分组

    • ?P<first_name>
    res = re.search(r"(\+?1)?[ .-]?\(?([\d]{3})\)?[ .-]?(?P<first_name>[\d]{3})[ .-]?([\d]{4})", "(213) 867-5309")
    print(res.group())
    print(res.groupdict())  # {'first_name': '867'}
    
  • 引用已经存在的分组

    • 可以使用\N回溯引用编号分组;\1 将会匹配第一个分组 或者$1

      res = re.search(r"<([\w_-]+)>stuff</\1>", "<foo>stuff</foo>")
      print(res.group())
      
9.5 先行断言
  • 先行断言:能够基于之后内容是否存在接受或拒绝一个匹配,而不是需要接下来的内容作为匹配的一部分。

    # `n(?!e)` 会匹配final中的na;Python中的n;无法匹配jasmine;仅仅返回n
    res = re.search(r"n(?!e)", "final")
    print(res)  # <_sre.SRE_Match object; span=(2, 3), match='n'>
    res = re.search(r"n(?!e)", "jasmine")
    print(res)  # None
    res = re.search(r"n(?!e)", "Python")
    print(res)  # <_sre.SRE_Match object; span=(5, 6), match='n'>
    
9.6 标记
  • 不区分大小写 re.IGNORECASEre.I

    • res = re.search(r"python", "Python Is Awesome", re.I)
      print(res)  # <_sre.SRE_Match object; span=(0, 6), match='Python'>
      
  • 点匹配换行符 re.DOTALLre.S

    • res = re.search(r".+", "foo\nbar")
      print(res)  # <_sre.SRE_Match object; span=(0, 3), match='foo'>
      res = re.search(r".+", "foo\nbar", re.S)
      print(res)  # <_sre.SRE_Match object; span=(0, 7), match='foo\nbar'>
      
  • 多行模式 re.MULTILINEre.M

    • # 导致仅能够匹配字符串开始`^`、结束`$`字符可以匹配字符串任意行的开始或结尾
      res = re.search(r"^bar", "foo\nbar")
      print(res)  # None
      res = re.search(r"^bar", "foo\nbar", re.M)
      print(res)  # <_sre.SRE_Match object; span=(4, 7), match='bar'>
      
  • 详细模式 re.VERBOSEre.X

    • 导致所有空白(除了在字符组中)被忽略,包括换行

    • # 字符当作注释字符

      expr = r"(?P<first_three>[\d]{3})-(?P<last_four>[\d]{4})"
      res = re.search(expr, "867-5309")
      print(res)  # <_sre.SRE_Match object; span=(0, 8), match='867-5309'>
      
      expr1 = r"""(?P<first_three>[\d]{3})        # the first three digits
                  -                              # A literal hyphen
                  (?P<last_four>[\d]{4})         # The last four digits 
                  """
      res = re.search(expr1, "867-5309", re.X)
      print(res)  # <_sre.SRE_Match object; span=(0, 8), match='867-5309'>
      
  • 调试模式 re.DEBUG 编译正则表达式将一些调试信息输出到sys.stderr

  • 使用多个标记 re.S|re.M

  • 内联标记

    • (?i) 等同于re.I

      print(re.search(r"(?i)FOO", "foo").group()) # foo
      
9.7 替换
  • re.sub()接受三个参数

    • 正则表达式
    • 用于替换的字符串 \1\2\3\4返回分组
    • 被搜索的原始字符串
    res = re.sub(r"(\+?1)?[ .-]?\(?([\d]{3})\)?[ .-]?([\d]{3})[ .-]?([\d]{4})",
                r"\1\2\3\4",
                 "(213) 867-5309")
    print(res)  # 2138675309
    
9.8 已编译的正则表达式
  • compile 返回一个已编译的正则表达式对象,该对象可以被重复使用

    res = regex.sub(r"(\2) \3-\4", "+1 213.867.5309")
    print(res)  # (213) 867-530
    
  • 发送的这两个值在返回的匹配独享的posendpos属性可用

    regex = re.compile("[\d]+")
    res = regex.search("1 mile is equal to 5280 feet.", pos=2)
    print(res) # <_sre.SRE_Match object; span=(19, 23), match='5280'
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壹如年少遲夏歸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值