一文搞懂Python中正则表达式

134 阅读4分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」。

Python 的 re 模块(Regular Expression 正则表达式)提供了各种正则表达式的匹配操作,在文本解析、复杂字符串提取时起到很重要的作用,本篇详细讲解 re 模块的使用。


re.match()

re.match() 从字符串的起始位置按模式匹配,如果匹配不成功,或者不是在起始位置匹配成功,返回 None 。匹配成功时返回一个结果对象。

re.match(pattern, string, flags=0)

  • pattern:匹配的正则表达式
  • string:源字符串
  • flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写、是否多行匹配等,如 re.I 匹配时忽略字符串中的大小写。
import re

print(re.match('aa', 'Aaaabc', flags=re.I))
print(re.match('aa', 'bbaabc', flags=re.I))

上面第一条结果返回成功匹配的对象,可以用 group(num)groups() 函数获取匹配结果,也可以用 span(num) 获取匹配结果在源字符串中开始和结束的位置。

先来看一下 group(num)groups() 的用法。

  • group(num=0):根据输入的组号(或多个组号),返回一个字符串(或元组),元组中包含组号的对应的撇皮结果。默认为 0,即返回 re.match() 匹配到的完整内容。
  • groups():返回一个包含指定组号字符串的元组,从 1 到 最后。

直接看例子更清晰

line = "Python新视野"
matchObj = re.match(r'(.*)新(.*)', line)

print("matchObj.group(0) : ", matchObj.group())
print("matchObj.group(1, 2) : ", matchObj.group(1, 2))
print("matchObj.groups() : ", matchObj.groups())

matchObj 匹配的所有结果其实就是 ('Python新视野', 'Python', '视野')group(num) 中的 num 实际就是匹配结果对应的索引,这样再来看上面的结果应该就很清晰了。同时可以看到 groups() 实际相当于 group(1, 2, ... , max)

明白了 group(num) 的用法,那么 span(num) 其实就很好理解,它与 group 的不同之处在于它的返回结果是匹配结果在源字符串中的起始与结束的索引。

print("matchObj.span(0) : ", matchObj.span(0))
print("matchObj.span(2) : ", matchObj.span(2))


re.search()

re.search () 在整个字符串匹配并返回第一个成功的匹配。

re.search(pattern, string, flags=0)

re.match()re.search() 的不同之处很好理解,re.match()只匹配开头的字符串,如果匹配失败,后面的将不再匹配,直接返回 None 。而 re.search() 是在整个字符串中匹配,如果起始位置没有匹配到,那么它会继续匹配剩余的字符串,直到第一次匹配成功,如果字符串结束都没有匹配成功,那么返回 None 。使用时要注意如果匹配失败的话就不能实用 span(num) 等函数获取匹配结果了哦!

看个例子。

try:
    print(re.search('aa','aaaabc').span())
    print(re.search('aa','bbaaac').span())
    print(re.search('aa','bbaccc').span())    # 匹配失败
except Exception as e:
    print(e)


re.findall()

re.findall() 用于在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。它与 re.match() 作用十分详细,唯一不同就是 re.match() 不但包含了字串,还包含了匹配到的完整结果。看个例子,一目了然!

re.findall(pattern, string, flags=0)

line = "Python新视野"
print('re.findall:', re.findall(r'(.*)新(.*)', line))
print('re.match:', re.match(r'(.*)新(.*)', line).group(0, 1, 2))


re.finditer()

re.finditer() 在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

re.finditer(pattern, string, flags=0)

result = re.finditer(r"\d+", "A1B2C3")
for match in result:
    print(match.group())


re.sub()

re.sub() 函数可以将字符串中满足匹配条件的内容全部替换

re.search(pattern, repl, string, count, flags=0)

  • repl:替换的字符串,可以是一个函数。
  • count:匹配成功后替换的最大次数,默认为0,表示替换所有的匹配。
line = 'sun是菜鸡'
# ?<= 匹配“是”后面的字符
print(re.sub(r'(?<=是).*', '大佬', line))

配合 lambda 使用

line = 'A2B2C3'
print(re.sub(r'(\d+)', lambda x: str(int(x.group())*2), line))


re.subn()

re.subn()re.sub() 用法相同,只是返回的结果中包含了替换的次数。

line = 'sun是菜鸡 向日葵是菜鸡'
print(re.sub(r'(?<=是).{2}', '大佬', line, count=1))
print(re.subn(r'(?<=是).{2}', '大佬', line, count=1))


re.split()

根据模式分割源字符串,返回一个包含结果子字符串的列表。

re.split(pattern, string, maxsplit=0, flags=0)

  • maxsplit:最大分割次数,默认为 0 ,表示进行最大次数的分割,如果 maxsplit 非零,则最多发生 maxsplit 次拆分,并且字符串的剩余部分作为列表的最后一个元素返回
print(re.split(r"\d+", "A1B2C3"))
print(re.split(r"\d+", "A1B2C3", 2))


re.compile()

re.compile() 用于编译正则表达式,生成一个正则表达式(Pattern)对象。re.compile() 可以搭配上面一些函数一起使用。

re.compile(pattern[, flags])

  • pattern:一个字符串形式的正则表达式。

re.compile() 的用法不难,但要注意的是当它与上面几个函数一起使用时,函数参数有些不同。

match()search()findall()finditer() 参数均增加了两个可选参数:

  • pos:可选参数,指定字符串的起始位置,默认为0。
  • endpos:可选参数,指定字符串的结束位置,默认为字符串的长度。
pattern = re.compile(r'\d+')
print(pattern.findall('A1B2C3'))
print(pattern.findall('A1B2C3', 0, 4))


对于刚入门 Python 或是想要入门 Python 的朋友,可以通过关注公众号“Python新视野”,一起交流学习,都是从新手走过来的,有时候一个简单的问题卡很久,但可能别人的一点拨就会恍然大悟,由衷的希望大家能够共同进步。另有整理的近千套简历模板,几百册电子书等你来领取哦!