【Python编程快速上手 —让繁琐工作自动化】——模式匹配与正则表达式

模式匹配与正则表达式

1 用正则表达式查找文本模式

  • 模块:import re

  • compile函数:向re.compile()传入一个字符串值,表示正则表达式,它将返回一个Regex 模式对象

  • Regex对象

    • 示例

      import re
      
      p = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
      mo = p.search('My number is 415-555-4242.')
      
      print(mo.group())
      

2 正则表达式中的符号

  • 利用括号分组:

    • 添加括号将在正则表达式中创建“分组”:(\d\d\d)-(\d\d\d-\d\d\d\d)
    • 可以使用group()匹配对象方法,从一个分组中获取匹配的文本
    p = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
    mo = p.search('My number is 415-555-4242.')
    
    print(mo.group(1))
    print(mo.group(2))
    print(mo.group())
    
    # 括号在正则表达式中有特殊的含义,但是如果需要在文本中匹配括号,就需要用倒斜杠对(和)进行字符转义。
    p = re.compile(r'(\(\d\d\d\))-(\d\d\d-\d\d\d\d)')
    mo = p.search('My number is (415)-555-4242.')
    print(mo.group(1))
    print(mo.group(2))
    
  • 用管道匹配多个分组

    字符|称为”管道“。希望匹配许多表达式中的一个时,就可以使用它。

    # 如果Batman 和Tina Fey 都出现在被查找的字符串中,第一次出现的匹配文本,将作为Match 对象返回
    r = re.compile(r'Batman|Tina Fey')
    mo1 = r.search('Batman and Tina Fey.')
    mo2 = r.search('Tina Fey and Batman')
    In[11]: mo1.group()
    Out[11]: 'Batman'
    
    In[12]: mo2.group()
    Out[12]: 'Tina Fey'
    
    • 指定前缀:batRegex = re.compile(r'Bat(man|mobile|copter|bat)')
  • 用问号实现可选匹配:batRegex = re.compile(r'Bat(wo)?man')

  • 用星号匹配零次或多次batRegex = re.compile(r'Bat(wo)*man')

  • 用加号匹配一次或多次batRegex = re.compile(r'Bat(wo)+man')

  • 用花括号匹配特定次数:

    • haRegex = re.compile(r'(Ha){3}')
    • haRegex = re.compile(r'(Ha){3,5}'):匹配’HaHaHa’、‘HaHaHaHa’和’HaHaHaHaHa’
  • 问号:贪心与非贪心

    • Python 的正则表达式默认是**“贪心”**的,这表示在有二义的情况下,它们会尽可能匹配最长的字符串

      greedyHaRegex = re.compile(r'(Ha){3,5}')

    • 花括号的“非贪心”版本匹配尽可能最短的字符串,即在结束的花括号后跟着一个问号。

      nongreedyHaRegex = re.compile(r'(Ha){3,5}?')

  • 方括号:自定义字符分类

    • 你可以用方括号定义自己的字符分类

      vowelRegex = re.compile(r'[aeiouAEIOU]')

    • 可以使用短横表示字母或数字的范围

    • 通过在字符分类的左方括号后加上一个插入字符(^),就可以得到“非字符类”。

      consonantRegex = re.compile(r'[^aeiouAEIOU]')

  • 美元与插入符号:

    • 可以在正则表达式的开始处使用插入符号(^),表明匹配必须发生在被查找文本开始处
    • 可以在正则表达式的末尾加上美元符号($),表示该字符串必须以这个正则表达式的模式结束
    • 可以同时使用^和$,表明整个字符串必须匹配该模式
  • 句点:通配字符

    • .(句点)字符称为“通配符”它匹配除了换行之外的所有字符,句点字符只匹配一个字符

    • 要匹配真正的句点,就是用倒斜杠转义:.

    • 用点-星匹配所有字符

      nameRegex = re.compile(r'First Name: (.*) Last Name: (.*)')

      • 点-星使用“贪心”模式:它总是匹配尽可能多的文本。要用“非贪心”模式匹配所有文本,就使用点-星和问号
        • nongreedyRegex = re.compile(r'<.*?>')
    • 用句点字符匹配换行

      • 点-星将匹配除换行外的所有字符。通过传入re.DOTALL 作为re.compile()的第二个参数,可以让句点字符匹配所有字符,包括换行字符

        newlineRegex = re.compile('.*', re.DOTALL)

3 findall()方法

  • search()将返回一个Match对象,包含被查找字符串中的“第一次”匹配的文本

  • findall()方法将返回一组字符串,包含被查找字符串中的所有匹配

    phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups
    mo = phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
    

4 字符分类

缩写字符分类表示
\d0-9的任何数
\D除0-9的任何数
\w任何字母、数字或下划线字符
\W除字母、数字或下划线的任何字符
\s空格、制表符或换行符
\S除空格、制表符或换行符的任何字符

5 compile的参数

  • 不区分大小写的匹配

    • 要让正则表达式不区分大小写,可以向re.compile()传入re.IGNORECASE 或re.I,作为第二个参数。

      robocop = re.compile(r'robocop', re.I)

  • 管理复杂的正则表达式

    • 你可以告诉re.compile(),忽略正则表达式字符串中的空白符和注释,并向re.compile()传入变量re.VERBOSE,作为第二个参数。

      phoneRegex = re.compile(r'''(
          (\d{3}|\(\d{3}\))?            # area code
          (\s|-|\.)?                    # separator
          \d{3}                        # first 3 digits
          (\s|-|\.)                     # separator
          \d{4}                        # last 4 digits
          (\s*(ext|x|ext.)\s*\d{2,5})?  # extension
          )''', re.VERBOSE)
      
  • 组合使用re.IGNOREC ASE、re.DOTALL 和re.VERBOSE

    • 如果你希望在正则表达式中使用re.VERBOSE 来编写注释,还希望使用re.IGNORECASE 来忽略大小写,遗憾的是,re.compile()函数只接受一个值作为它的第二参数。可以使用管道字符(|)将变量组合起来,从而绕过这个限制。管道字符在这里称为“按位或”操作符。

      someRegexValue = re.compile('foo', re.IGNORECASE | re.DOTALL | re.VERBOSE)

6 用sub()方法替换字符串

  • Regex对象的sub()方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式。

    namesRegex = re.compile(r'Agent \w+')
    mo = namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.')
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

From Star.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值