python之正则表达式及re模块

1 正则表达式

字符串处理是编程中常遇见的问题,如:字符串的增、删、改、查等,其首要问题是字符串的匹配,正则表达式正是用来解决这个问题的。

正则表达式,又称规则表达式(Regular Expression,在代码中常简写为regex、regexp或re)

给定一个正则表达式和一个字符串,可以达到如下的目的:

  1. 判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);

  2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。

正则表达式语法:

见参考1,2

  • 字符

    字符 描述 等价于
    . 匹配除换行符以外的任意字符
    \w 匹配字母、数字、下划线 [A-Za-z0-9_]
    \W 匹配任何非单词字符(匹配非字母、非数字、非下划线) [^A-Za-z0-9_]
    \d 数字,匹配一个数字字符 [0-9]
    \D 非数字,匹配一个非数字字符 [^0-9]
    \s 空白, 匹配任何空白字符,包括空格、制表符等。
    \S 非空白,匹配任意不是空白符的字符
    \t 匹配一个水平制表符tab
    \b 匹配单词的开始或结束
    \B 匹配不是单词开头或结束的位置
    [^x] 匹配除了x以外的任意字符
  • 数量表示

    字符 描述 等价于
    * (前面的字符)重复0次或多次
    + (前面的字符)重复1次或多次
    (前面的字符)重复0次或1次
    匹配前面的表达式n个
    (前面的字符)重复n次或更多次(至少重复n次)
    (前面的字符)重复n到m次
  • 范围集合

    字符 描述
    x|y 匹配 x 或 y, | 的算符优先级较低
    [xyz] 字符集合,匹配包含的任意一个字符
    [^xyz] 字符集取反,匹配未包含的任意字符
    [a-z] 字符范围,匹配指定范围内的任意字符,可以连写: [a-zA-Z0-9]
    [^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符
  • 边界字符

    字符 描述
    ^ 匹配输入字符串开头位置
    $ 匹配输入字符串结尾的位置
    \b 匹配单词的开始或结束比如Sheep\b可以匹配CodeSheep末尾的Sheep,不能匹配CodeSheepCode中的Sheep
    \B 匹配不是单词开头或结束的位置比如Code\B可以匹配HelloCodeSheep中的Code,不能匹配HelloCode中的Code
  • 分组和引用

    字符 描述
    (expression) 分组。匹配括号里的整个表达式。
    (?:expression) 非捕获分组。匹配括号里的整个字符串但不获取匹配结果,不进行存储供以后使用
    \num 对前面所匹配分组的引用。比如(\d)\1可以匹配两个相同的数字,(Code)(Sheep)\1\2则可以匹配CodeSheepCodeSheep
  • 预查断言

    字符 描述
    (?=) 正向预查。比如Code(?=Sheep)能匹配CodeSheep中的Code,但不能匹配CodePig中的Code
    (?!) 正向否定预查。比如Code(?!Sheep)不能匹配CodeSheep中的Code,但能匹配CodePig中的Code
    (?<=) 反向预查。比如(?<=Code)Sheep能匹配CodeSheep中的Sheep,但不能匹配ReadSheep中的Sheep
    (?<!) 反向否定预查。比如(?<!Code)Sheep不能匹配CodeSheep中的Sheep,但能匹配ReadSheep中的Sheep
  • 模式修正符

    字符 描述
    i (ignore case) 不区分大小写
    m (mulitipleline)多行搜索(将字符串视为多行,不管是哪行都能匹配)
    s (singleline) 将字符串视为单行,转义回车换行符作为普通字符
    g (global) 全局匹配

2 python中的Re模块

2.1 字符串的查找方法

先说一下不import re模块时,python字符串也有一些字符串匹配方法,只不过功能较简单,不能进行复杂的字符串匹配。

字符串方法 描述
str.startswith(str1) 检查字符串是否以str1开头
str.endswith(str1) 检查字符串是否以str1结尾
str.find(str1, start=0, end=len(str)) 检查str1是否在str中,只检查str[star, end]范围内
str.rfind() rfind和find()方法类似,不过是从右边开始查找
str.index(str1, start=0, end=len(str1)) index和find()方法类似,只不过str1在str中不存在就会报错
str.rindex() rindex和index()方法类似,不过是从右边开始查找

示例:

if __name__ == '__main__':
    string = "just a test"
    # startswith 方法,检查字符串是否以str1开头
    res = string.startswith('jus')
    print(f'startswith res = {res}') # 结果: res = True
    # endswith 方法,检查字符串是否以str1开头
    res = string.endswith('est')
    print(f'endswith res = {res}')   # 结果: res = True
    
    # find 方法
    res = string.find('a t')
    print(f'find res = {res}')       # 结果: res = 5
    # 字符串 0 - 5 中没有'a t',应返回-1
    res = string.find('a t', 0, 5)
    print(f'find strip res = {res}') # 结果: res = -1
    
    # index方法,检测某个子串是否包含在这个字符串中,
    # 如果在返回这个子串开始的位置下标,否则则报异常
    res = string.index('a t')
    print(f'index res = {res}')      # 结果: res = 5
    # 不存在报异常
    res = string.index('a t', 0, 5)
    print(f'index strip res = {res}')# 不存在报错
    
    # rfind与rindex 从右向左侧找
    res = string.rfind('est')
    print(f'rfind res = {res}')     # 结果:res = 8,还是从左到右数
    
    res = string.rindex('est')
    print(f'rindex res = {res}')    # 结果:res = 8

2.2 python中的re模块

python中提供re(正则表达式)模块,用来匹配处理字符串。

re方法 描述
re.match 从字符串起始位置匹配
re.search 扫描整个字符串,并返回第一个成功的匹配
re.findall 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表
(match 和 search 是匹配一次,findall 匹配所有)
re.finditer finditer和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,
并把它们作为一个迭代器返回。
re.compile compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,
供 match() 、search()、findall 这些函数使用。

以下分别进行描述:

re.match函数:

import re

if __name__ == '__main__':
    # re.match(pattern, string, flags=0)
    line = "Cats are smarter than dogs"
    pattern = r'(.*) are (.*?) (.*)'
    matchObj = re.match(pattern, line, re.M|re.I)
     
    if matchObj:
       print("matchObj.group() : ", matchObj.group()) # matchObj.group(0)
       print("matchObj.group(1) : ", matchObj.group(1))
       print("matchObj.group(2) : ", matchObj.group(2))
       print("matchObj.group(3) : ", matchObj.group(3))
    
       print("matchObj.groups : ", matchObj.groups())

# 输出:
'''
matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter
matchObj.group(3) :  than dogs
matchObj.groups :  ('Cats', 'smarter', 'than dogs')
'''

re.search函数:

import re

if __name__ == '__main__':
    # re.search(pattern, string, flags=0)
    line = "Cats are smarter than dogs, dogs smarter than chicken"
    pattern = '(smarter)'
    matchObj = re.search(pattern, line, re.M|re.I)
     
    if matchObj:
       print("matchObj.group() : ", matchObj.group())
       print("matchObj.group() : ", matchObj.group(1))

       print("matchObj.groups : ", matchObj.groups())

# 输出,只能匹配一个,且扫描整个字符串
'''
matchObj.group() :  smarter
matchObj.group() :  smarter
matchObj.groups :  ('smarter',)
'''

re.findall函数:

import re

if __name__ == '__main__':
    # re.findall(pattern, string, flags=0)
    line = "Cats are smarter than dogs, dogs smarter than chicken"
    pattern = '(smarter)'
    matchObj = re.findall(pattern, line, re.M|re.I)
     
    if matchObj:
       print("matchObj: ", matchObj)

# 输出, 找到正则表达式所匹配的所有子串,并返回一个列表
'''
matchObj:  ['smarter', 'smarter']
'''

re.finditer函数:

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

import re

if __name__ == '__main__':
    # re.finditer(pattern, string, flags=0)
    line = "Cats are smarter than dogs, dogs smarter than chicken"
    pattern = 'smarter'
    matchObj = re.finditer(pattern, line, re.M|re.I)
    # 可迭代对象 
    for it in matchObj:
        print(it.group(), it.span())
 
# 输出
'''
smarter (9, 16)
smarter (33, 40)
'''

re.compile函数:

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match, search, findall等方法使用 。

重写上述例子为:

pattern.match:

import re

if __name__ == '__main__':
    # pattern.match(string)
    line = "Cats are smarter than dogs"
    pattern = r'(.*) are (.*?) (.*)'
    # re.compile(pattern[, flags])
    pa = re.compile(pattern, re.M|re.I)
    matchObj = pa.match(line)
     
    if matchObj:
       print("matchObj.group() : ", matchObj.group()) # matchObj.group(0)
       print("matchObj.group(1) : ", matchObj.group(1))
       print("matchObj.group(2) : ", matchObj.group(2))
       print("matchObj.group(3) : ", matchObj.group(3))
    
       print("matchObj.groups : ", matchObj.groups())

pattern.search:

import re

if __name__ == '__main__':
    # pattern.search(string)
    line = "Cats are smarter than dogs, dogs smarter than chicken"
    pattern = '(smarter)'
     # re.compile(pattern[, flags])
    pa = re.compile(pattern, re.M|re.I)
    matchObj = pa.search(line)
     
    if matchObj:
       print("matchObj.group() : ", matchObj.group())
       print("matchObj.group() : ", matchObj.group(1))

       print("matchObj.groups : ", matchObj.groups())

pattern.findall:

import re

if __name__ == '__main__':
    # pattern.findall(string)
    line = "Cats are smarter than dogs, dogs smarter than chicken"
    pattern = '(smarter)'
    pa = re.compile(pattern, re.M|re.I)
    matchObj = pa.findall(line)
     
    if matchObj:
       print("matchObj: ", matchObj)

pattern.finditer:

import re

if __name__ == '__main__':
    # pattern.finditer(string)
    line = "Cats are smarter than dogs, dogs smarter than chicken"
    pattern = 'smarter'
    pa = re.compile(pattern, re.M|re.I)
    matchObj = pa.finditer(line)
     
    # 可迭代对象 
    for it in matchObj:
        print(it.group(), it.span())

参考:

1 正则表达式解析器

2 https://r2coding.com/#/README?id=正则表达式

3 python基础教程

posted @ 2022-08-28 11:50  sureZ_ok  阅读(234)  评论(0编辑  收藏  举报