Python之第三十三天的努力--re模块

re模块

  1. re.findall()和re.search()

    • import re
      ret = re.findall('\d+','18746asd8784sds')
      print(ret)              # ['18746', '8784']
      
      ret = re.search('\d+','18746asd8784sds')
      print(ret)              # 变量    # <re.Match object; span=(0, 5), match='18746'>
      if ret:
          print(ret.group())      # 18746
      
    • # findall 还是按照完整的正则进行匹配,只是总是只显示括号里匹配的内容
      ret = re.findall('8(\d)\d','18746asd8784sds')
      print(ret)                  # ['7', '7']
      
    • # search 还是按照完整的正则进行匹配,显示页显示匹配到的第一个内容
      # 但是我们可以通过group方法传参数,来获取具体分组中的内容
      ret = re.search('8(\d)(\d)','18746asd8784sds')
      print(ret)
      if ret:
          print(ret.group())      # 874
          print(ret.group(1))     # 7
          print(ret.group(2))     # 4
      
    • findall

      • 获取所有符合条件的,优先显示分组中的
    • search 只取第一个符合条件的,没有优先显示这件事

      • 得到的结果是一个变量
        • 变量.group() 的结果 完全和 变量.group(0)的结果一致
        • 变量.group(n) 的形式来指定获取第n个分组中匹配到的内容
    • 为什么在search中不需要分组优先 而在findall中需要

      • 加上括号 是为了对真正需要的内容进行提取

        # 加上括号 是为了对真正需要的内容进行提取
        # 获取第一个<>和第二个<> 中间的内容 --->  ads4848esdfafd
        ret = re.findall('<\w+>(\w+)</\w+>','<h1>ads4848esdfafd</h1>')
        print(ret)          # ['ads4848esdfafd']
        
        ret = re.search('<\w+>(\w+)</\w+>','<h1>ads4848esdfafd</h1>')
        print(ret.group())  # <h1>ads4848esdfafd</h1>
        print(ret.group(1)) # ads4848esdfafd
        
    • # 为什么要用分组,以及findall的分组优先到底有什么好处
      exp = '2-3*(5+6)'
      
      # 匹配 a+b 并且计算他们的结果
      ret = re.search('(\d+)[+](\d+)',exp)
      print(ret)
      print(ret.group(1))                             # 5
      print(ret.group(2))                             # 6
      print(int(ret.group(1)) + int(ret.group(2)))    # 11
      
    • with open('douban.html',encoding='utf-8') as f:
          content = f.read()
      ret = re.findall('<span class="title">(.*?)</span>\s*<span class="title">.*?</span>',content)
      print(ret)
      
    # 如果我们要查找的内容在一个复杂的环境中
    # 我们要查的内容并没有一个突出的 与众不同的特点 甚至会和不需要的杂乱的数据混在一起
    # 这个时候我们就需要把所有的数据都统计出来,然后对这个数据进行筛选,把我们真正需要的数据对应的正则表达式用()圈起来
    # 这样我们就可以筛选出真正需要的数据了
    
    • ret = re.findall('1(\d)(\d)','123124')
      print(ret)          # [('2', '3'), ('2', '4')]
      # (?:.....)改分组不显示
      ret = re.findall('1(?:\d)(\d)','123124')
      print(ret)          # ['3', '4']
      
    • 什么是爬虫?

      • 通过代码获取一个网页的源码

        import requests
        ret = requests.get('https://home.cnblogs.com/')
        print(ret.content.decode('utf-8'))
        
      • 要的是源码中嵌着的网页上的内容

    • 分组和findall的现象

      • 为什么要用分组?
        • 把想要的内容放在分组里
    • 如何取消分组优先

      • 如果在写正则的时候由于不得已的原因 导致不要的内容也得写在分组里
      • (?😃 取消这个分组的优先显示
  2. split

    ret = re.split('\d+','zs222ls')
    print(ret)                      # ['zs', 'ls']
    
    ret = re.split('(\d+)','zs222ls')
    print(ret)                      # ['zs', '222', 'ls']
    
  3. sub 替换

    ret = re.sub('\d+','H','zs123ls789')
    print(ret)                      # zsHlsH
    
    ret = re.sub('\d+','H','zs123ls789',1)
    print(ret)                      # zsHls789
    
  4. subn

    ret = re.subn('\d+','H','zs123ls789')
    print(ret)                      # ('zsHlsH', 2)
    
  5. match

    # match     
    # 从头开始找
    # 用户输入内容匹配的时候,要求用户输入11位手机号,^手机号正则$
    # 用来规定这个字符串必须是什么样的。
    ret = re.match('\d+','abc123qwer456')
    print(ret)                      # None
    
    ret = re.match('\d+','123abc456qwer')
    print(ret)                      # <re.Match object; span=(0, 3), match='123'>
    print(ret.group())              # 123
    
    # 相当于
    ret = re.search('^\d+','123abc456qwer')
    
  6. compile

    # compile   节省代码时间的工具
    # 当同一个正则表达式要被使用多次时
    # 节省了多次解析同一个正则表达式的时间
    ret = re.compile('\d+')
    res1 = ret.search('asd515f41wefe45')
    print(res1)                         # <re.Match object; span=(3, 6), match='515'>
    res2 = ret.findall('asd515f41wefe45')
    print(res2)  
    
  7. finditer

    # finditer  节省空间
    ret = re.finditer('\d+','asd515f41wefe45')
    for i in ret:
        print(i)
        print(i.group())
        # <re.Match object; span=(3, 6), match='515'>
        # 515
        # <re.Match object; span=(7, 9), match='41'>
        # 41
        # <re.Match object; span=(13, 15), match='45'>
        # 45
    
  8. compile和finditer

    # 先compile(如果没有重复使用一个正则,也不能节省时间) 
    # 再finditer
    ret = re.compile('\d+')
    res = ret.finditer('asd515f41wefe45')
    for i in res:
        print(i.group())
    # 515
    # 41
    # 45
    
  9. 分组命名

    • (?P<名字>正则表达式)

      ret.group('名字')

      # 分组命名
      # (?P<名字>正则表达式)
      # ret.group('名字')
      ret = re.search('\d(\d)\d(\w+?)(\d)(\w)\d(\d)\d(?P<name1>\w+?)(\d)(\w)\d(\d)\d(?P<name2>\w+?)(\d)(\w)',
                '123abc45678qwer_123abc45678qwer123abc45678qwer')
      print(ret)
      print(ret.group('name1'))
      print(ret.group('name2'))
      
    • 分组命名的引用

      • (?P<名字>) 引用 (?P=名字)

        # (?P<名字>)    引用  (?P=名字)
        # <abc>asdf123456+*ghjkl</abc>  --->  <\w+>.*?</\w+>
        exp = '<abc>asdf123456+*ghjkl</abc>'
        # ret = re.search('<\w+>.*?</\w+>',exp)
        # print(ret)      # <re.Match object; span=(0, 28), match='<abc>asdf123456+*ghjkl</abc>'>
        
        ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',exp)
        print(ret)
        
      • r'正则' ---> 用 \1来表达第一组

        # r'正则'  ---> 用 \1来表达第一组
        exp = '<abc>asdf123456+*ghjkl</abc>'
        ret = re.search(r'<(\w+)>.*?</\1>',exp)
        print(ret)
        
  10. 一个练习

    # 练习
    # 找出‘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 = filter(lambda n:n,ret)
    print(list(ret))    # ['1', '2', '60', '5', '4', '3']
    

    有时我们要匹配的内容是包含在不想要的内容之中的

    ​ 只能先把不想要的内容匹配出来,然后再想办法从结果中去掉

posted @ 2020-07-15 21:12  ET-珩  阅读(89)  评论(0)    收藏  举报