Python的正则表达式(元字符、组合、经典表达、匹配函数)

正则表达式模块 re 字符使用详解

正则表达式,就是一个特殊的字符串。
本文包括正则表达式生成和使用两个部分:

  1. 正则表达式生成:字符的选用和组合(一、二、三、四)
  2. 正则表达式使用:拿生成的正则表达式,去匹配一个字符串中包含该正则表达式的部分(五)

一、字符类型(组合正则表达式)

  • 普通字符(非元字符):在匹配字符串是只与自己匹配
  • 14个元字符:. ^ $ ? + * \ | [ ] { } ( ) (8+6)
    1. 通配符. 转义字符\ 选择字符|
    2. 集合字符 [^-]
    3. 重复字符 *+?{,}
    4. 括号()
    5. 首尾字符^$
    6. 被转义的普通字符
      十进制\d 数字字母\w 空白\s
      大写时取补集

    匹配字符时特殊字符,注意转义字符的使用

详述元字符作用

  1. 匹配单字符
    1. .匹配单个字符
    2. […] 字符集内的单个字符,
      [abc]、所有十进制[0-9]、所有数字和字母[0-9a-zA-Z]
    3. [^…]非字符集,排除该字符,取补集
      [^abc]、 [^0-9]所有非十进制,[^\t\v\n\f\r]非空白字符
  2. 字符重复
    1. * 前一个字符零次或多次扩展
      ab*表示a,abb等
    2. + 前一个字符1次或多次
    3. ? 前一个字符0次或1次
    4. {m} 扩展前一个字符m次
      [2-9][0-9]{7}(总共七位数字)
    5. {m,n} 扩展前一个字符m到n次
      关于字符重复都能用它写
      1. a* == a{0,infinity}
      2. a+ == a{1,infinity}
      3. a? == a{0,1}
      4. a{m} == a{m,m}

      {m,n} 是贪婪匹配,会要重复次数最接近n的字符
      破解:字符重复语句后面加一个问号?就可以不贪婪,例a+?、a{m,n}?

  3. 匹配多字符
    1. | 或:
      左右任意一个 abc|def
    2. (…) 分组标记
      内部可以使用|操作符
  4. 位置控制
    1. ^ 匹配开头,^abc表示abc且在一个字符串开头
    2. $ 匹配字符串结尾(行尾)
  5. 补充:可打印字符(非)
    1. \d 0-9 \D 所有非十进制的字符
    2. \w [a-z0-9A-Z] \W 作用相反,非字母数字字符
    3. \s 匹配空白符,等价于[\n\s\r\v\f] \S 非空白
    4. \b 匹配单词边界(非字母是单词边界) \B与\b作用相反
    5. \n 匹配已保存的子组 n是数字 ,()是获取组
    6. \A 匹配字符串的开始
    7. \Z 匹配字符串的结束

二、特殊的组合结构

  1. 正顺序组合αβ
  2. 选择组合α|β(既匹配又匹配)
  3. 星号α*(与α匹配的任意多个片段(0))
  4. () 中的当成一个组

三、经典的正则表达式语法

  1. ^[A-Za-z]+$ 由字母组成的str
  2. ^[A-Za=z0-9]+$ 或^-?\d+$ 由数字组成的字符串
  3. ^[0-9]?[1-9][0-9]*$ 正整数
  4. [1-9]\d{5} 6位邮政编码
  5. [\u4e00-\u9fa5] 中文字符
  6. \d{3}-\d{8}|d{4}-\d{7} 国内电话
  7. 25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d IPv4的地址

正则表达式的表示类型

  1. 原生字符串 R’‘或r’’:表示原来的内容
  2. 表达能力:正则表达式> 普通字符串>原生字符串

四、正则表达式的使用

两种匹配方法

  1. 普通匹配
    re.search(“正则表达式”,“待匹配的字符串”)
  2. compile和模式pattern
    生成:p = re.compile(pattern)
    使用:p.search(“待匹配的字符串”)
    p = re.compile('abc') ;
    m = p.search('AabcDabcE')
    

    目的:假如某个正则表达式,需要用来匹配多个字符串,则可以先将该正则表达式编译(compile)成一个模型(pattern)。

常用的匹配函数

  1. search (对字符串的模式搜索,返回re.Matchobject)
    group 显示结果

    m = re.search('abc','AabcD');print(m.group())
    
  2. findall (所有匹配,返回一个列表)(没有索引?for x in lst)

  3. finditer (findall类似,返回一个迭代器,用完自动释放内存

  4. match (seach类似,只从头开始匹配,开头没有None)(\A)

  5. fullmatch (从头开始,整个字符串)

  6. split (用pattern作为分割符,maxsplit,返回一个list)
    比普通字符串中的split强大,因为可以匹配

  7. sub(pattern,repl,字符串)将字符串中pattern替代成repl
    count参数,可以限制最大的替换次数

    phone = "2004-959-559";num = re.sub(r'\D',"",phone)
    
  8. subn (类似sub,返回被替换后的字符串和替换次数,的元组)

  9. enum (保存了所有的修饰符,all modifiers)

    • re.I(ignorecase) 在search中可以忽略大小写
    • re.S(dotall) 可匹配包括换行符在内的单个字符
    • re.M(multilines) 多行,^$ 会受影响,启用时表示行首而不是串首。\A 和 \Z 不受影响,表示串首
  10. group 对正则表达式进行分组,()最多99个分组,\n 访问

    p = r'(A)(B(C))D'
    s = '1ABCD2'
    m = re.search(p,s)
    print(m.group())
    print(m.group(1))
    print(m.group(2))  # 几级运算
    print(m.group(3))
    
    1. start(),end() 某序号分组的元素的开始和结束
    2. \n 表示第几个分组,从1开始:数左括号确定是第几组
    3. 对分组的引用,\1,\2 \g<name > P=name)等称为反向引用是指在对字符串匹配的过程中,可以调用已匹配到的分组,进行匹配。

      为组取名:?P<name> 调用时 \2 表示第2分组

      s = 'To be, or not to be to'
      m1 = re.search(r'(\w+).*?\1',s,re.I)
      #其中\1表示,将(\w+)捕获的分组,反向引用用来匹配字符串
      print(m1.group())  # To be, or not to
      print(m1.groups())  # ('To',)
      
    4. (?:…) 决定的分组,称为非捕获分组(内部为正则表达式)
      m = re.search(r'(?P<FirstName>\w+)','MingWu')
      m.groups()  
      
  11. 环视:

  • 肯定前视 (?= ) 向前看未读的,前面才要

    s = '无名喜欢吃苹果和桔子'
    m = re.search(r'苹果(?=.+?桔子)',s) # .+? 表示通配符
    print(m.group())
    
  • 否定前视(?! )

  • 肯定后视(?<=)

    s = '无名喜欢吃苹果和桔子'
    m = re.search(r'(?<=苹果.)桔子',s)
    print(m.group())
    
  • 否定后视(?<!)

猜你喜欢

转载自blog.csdn.net/weixin_43899514/article/details/109344619