Loading

15-正则表达式

正则表达式三个方法

  • Regular Expression

    • 匹配有规则的字符串
  • import re

  • re.match()

    • 匹配字符串是否以指定正则表达式开头
      • res = re.match('\d+', '123456') # object,返回对象或者None
  • re.search()

    • 匹配字符串是否包含表达式

      • res2 = re.search('oog', 'google') # object,返回对象或者None

        • # re.I忽略大小写
          res2 = re.search('GOO', 'google', re.I)  # object
          
  • re.findall()

    • 获取所有匹配的子字符串,返回的是列表
      • res3 = re.findall('goo', 'google google google') # ['goo', 'goo', 'goo'],如果匹配不到则返回空列表

匹配单个字符

  • .
    • . 表示匹配任意单个字符,除了换行\n
    • 注意r''只能消除字符串中的语义,不影响正则的语义,因此要匹配点(.),需要在点前加\
    • print(re.search('go.gle', 'go\ngle', re.S)) # 对象
      • re.S可以让 . 匹配\n
  • []
    • 表示匹配单个字符的范围
    • [abc]:匹配a或b或c
    • [a-zA-Z0-9_]:匹配数字字母下划线
    • print(re.search('go[a-zA-Z0-9_]gle', 'go_gle')) # 对象
  • \d
    • 表示数字,等价于[0-9]
    • \D :表示非数字,等价于[^0-9]
    • print(re.search('go\dgle', 'go8gle')) # 对象
  • \w
    • 表示数字字母下划线,等价于[a-zA-Z0-9_]
    • \W表示非数字字母下划线,等价于[^a-zA-Z0-9_]
    • print(re.search('go\wgle', 'go8gle')) # 对象
  • \s
    • 表示空格 或换行\n 或 制表符\t 或 换页符\f 回车符\r
    • \S表示非(空格 或换行\n 或 制表符\t 或 换页符\f 回车符\r)
    • print(re.search('go\Sgle', 'go gle')) # None

表示数量的符号

  • ?
    • 表示前面的字符可以出现0次或1次
      • print(re.findall('go?gle', 'google')) # [] # 非贪婪(最多匹配一个)
  • +
    • 表示前面的字符可以出现1次或多次
    • print(re.findall('go+gle', 'gooogle')) # ['gooogle'] # 贪婪(尽量多个匹配)
  • *
    • *表示前面的字符可以出现0次或多次
      • print(re.findall('g.*gle', 'g123abc,.;gle')) # ['g123abc,.;gle']
  • {}
    • 表示前面字符出现的次数范围
    • {3} :表示前面字符出现3次
    • {2, 5} :表示从2次~5次之间
      • print(re.findall('go{2,5}gle', 'gooogle')) # ['gooogle'],2和5之间不能加空格 # 贪婪

边界符号(锚字符)

  • ^
    • ^ :开头匹配
  • $
    • $ :结尾匹配
  • ^$
    • ^$ :完全匹配:除了正则中的字符串以外,不可以有其他多余的字符
  • 其他边界字符串
    • \A\Z
      • 与^$作用基本一致
      • 区别
        • print(re.findall('^#', '#google\n#baidu\n#360', re.M)) # ['#', '#', '#']
        • print(re.findall('\A#', '#google\n#baidu\n#360', re.M)) # ['#']
        • re.M
          • re.M: 换行模式
  • \b
    • 以单词结尾
    • \B以非单词结尾
  • chinesePattern = "[\u4e00-\u9fa5]+"

分组和捕获

  • 分组

    • ()

      • () :表示整体,还可以表示分组

        • s = '0755-88888888'
          pattern = '(\d{4})-(\d{8})'
          # pattern = '\d{4}-\d{8}'
          res = re.search(pattern, s)
          
      • print(res.group()) # '0755-88888888'

      • print(res.group(0)) # '0755-88888888'

      • print(res.group(1)) # '0755', 第一个分组(第一个括号的内容)

      • print(res.group(2)) # '88888888', 第二个分组(第二个括号的内容)

      • print(res.groups()) # ('0755', '88888888'),获取所有分组

  • 捕获

    • 用findall(),返回列表

      • pattern = r'(\d+)万到(\d+)万卢比'
        res = re.findall(pattern, s)  # 捕获()里面的
        print(res)  # [('15', '40')]
        
      • 别名

        • ?P<别名>

          • pattern = r'(?P<start>\d+)万到(?P<end>\d+)万卢比'
            res = re.search(pattern, s)
            print(res.group('end'))  # 40
            print(res.group('start'))  # 15
            
  • 编译正则

    • 编译正则:创建一个正则表达式对象,效率更高

      • # re.compile()
        
        pattern = re.compile(r'(\d+)万到(\d+)万卢比')
        res = pattern.findall(s)
        print(res)  # [('15', '40')]
        
  • 非捕获性分组

    • ?:

      • pattern = r'(\d+)万到(?:\d+)万卢比'
        res = re.findall(pattern, s)
        print(res)  # ['15']
        

其他正则函数

  • re.finditer

    • 匹配后的结果=>迭代器

      • res = re.finditer(r'\d+', '123abc456def678')
        print(res)  # 迭代器,<callable_iterator object at 0x0000026B6059F7C8>
        for i in res:
            # print(i)
            print(i.group(), i.span())
        '''
        123 (0, 3)
        456 (6, 9)
        678 (12, 15)
        '''
        
  • re.split

    • 分割/拆分

      • s = 'hello world'
        print(re.split(r'l|\s', s))  # ['he', '', 'o', 'wor', 'd']
        print(re.split(r'l|o', s))  # ['he', '', '', ' w', 'r', 'd']
        
      • |表示或者

  • re.sub

    • 替换

      • s = 'today is a good day today is a nice day'
        print(re.sub(r'\s', '-', s))  # today-is-a-good-day-today-is-a-nice-day
        print(re.subn(r'\s', '-', s))  # ('today-is-a-good-day-today-is-a-nice-day', 9)
        

补充

  • 空白行
    • \n\s*\r
  • 前后空白字符串
    • ^\s*|\s*$
  • 零宽断言
    • ?=exp
      • 断言当前位置后面能匹配exp
    • ?<=exp
      • 断言当前位置前面能匹配exp
    • ?!exp
      • 断言当前位置后面不能匹配exp
    • ?<!exp
      • 断言当前位置前面不能匹配exp
posted @ 2020-11-20 17:51  lotuslaw  阅读(118)  评论(0编辑  收藏  举报