Skip to content

re 模块

正则表达式是一种技术,不仅是在 python、java、go 等编程语言中可以使用,在很多的软件中也支持。

python 中最常用的方式,就是 re 模块。

re.findall

搜索字符串,以列表形式返回所有匹配结果

python
import re

ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)

运行结果:

['9999', '7890', '12345']

re.search 扫描整个字符串,并返回第一个成功的匹配

python
import re

ret = re.search('\d+', ' 540775360@qq.com')
ret.group()

运行结果:

540775360

re.match

re.match 从字符串的起始位置匹配一个模式,起始位置匹配不成功就返回 None

python
import re

result = re.match('\d+', ' 540775360@qq.com')
print(result)
print(result.group())
print(result.span())

re.sub

替换字符串中每一个匹配的字串,并返回替换后的结果

re.sub("正则表达式规则", "匹配到之后进行的处理", "需要从那个字符串里面匹配")

需求:将匹配到的阅读次数加 1

方法1:

python
# coding=utf-8
import re

ret = re.sub(r"\d+", '998', "python = 997")
print(ret)

运行结果:

python
python = 998

案例2:将 QQ 中间四位替换为 * 影藏。

python
import re

mail = """
354573548@qq.com
345436548@qq.com
pyxxponly@qq.com
122874244@qq.com
"""


def func(temp):
    temp = temp.group()
    return temp[:3] + "****" + temp[7:]


# 在原有的字符串上进行修改
ret = re.sub("([0-9a-zA-Z]+)@[0-9a-zA-Z]+.[0-9a-zA-Z]+", func, mail)
print(ret)

运行结果:

354****48@qq.com
345****48@qq.com
pyx****ly@qq.com
122****44@qq.com

re.compile

将正则表达式字符串编译成正则对象,以便于复用该模式

python
import re

text = """
yanglong985@163.com
深入物联2
a751524375@qq.com,感谢楼主,好人卡已发送
收起回复3楼2018-07-04 11:00
RAVV2017: 好滴,751524375@qq.com,是这个邮箱吗?
2018-7-4 11:04回复
Exhausted_Hero: 收到了吗,可否转发一份,好人卡给你410105411@qq.com
2018-10-1 18:50回复
以上的邮箱,已发,还需要的请回复邮箱。两套物联网学习资料。
回复(4)7楼2018-07-04 16:06
初识物联1
397872410@qq.com,谢谢楼主
物联博士5
1459543548@qq.com
谢谢谢谢
123456748973521324564132156465
1459543548@qqacom
"""

# compile 编译一个可以重复使用者正在表达式匹配对象
compile = re.compile("\d{5,11}", re.S)

# 每一次在匹配之前,都会将字符串编译成正在表达式匹配对象
print(re.findall(compile, text))
print(re.search(compile, text))
print(re.match(compile, text))

print(compile.findall(text))
print(compile.search(text))
print(compile.match(text))

附录

正则表达式符号复习

本章介绍了许多表示法,所以这里快速复习一下学到的内容:

  • ? 匹配零次或一次前面的分组。
  • * 匹配零次或多次前面的分组。
  • + 匹配一次或多次前面的分组。
  • {n} 匹配 n 次前面的分组。
  • {n,} 匹配 n 次或更多前面的分组。
  • {,m} 匹配零次到 m 次前面的分组。
  • {n,m} 匹配至少n次、至多 m 次前面的分组。
  • {n,m}?*?+? 对前面的分组进行非贪心匹配。
  • ^spam 意味着字符串必须以 spam 开始。
  • spam\$ 意味着字符串必须以 spam 结束。
  • .匹配所有字符,换行符除外。
  • \d\w\s 分别匹配数字、单词和空格。
  • \D\W\S 分别匹配出数字、单词和空格外的所有字符。
  • [abc] 匹配方括号内的任意字符(诸如a、b或c)。
  • [^abc] 匹配不在方括号内的任意字符。

不区分大小写的匹配

通常,正则表达式用你指定的大小写匹配文本。例如,下面的正则表达式匹配完全不同的字符串:

python
regex1 = re.compile('RoboCop')
regex2 = re.compile('ROBOCOP')
regex3 = re.compile('robOcop')
regex4 = re.compile('RobocOp')

但是,有时候你只关心匹配字母,不关心它们是大写或小写。要让正则表达式不区分大小写,可以向re.compile() 传入 re.IGNORECASEre.I,作为第二个参数。在交互式环境中输入以下代码:

python
>>> robocop = re.compile(r'robocop', re.I)
>>> robocop.search('RoboCop is part man, part machine, all cop.').group()
'RoboCop'
>>> robocop.search('ROBOCOP protects the innocent.').group()
'ROBOCOP'
>>> robocop.search('Al, why does your programming book talk about robocop so much?').group()
'robocop'

管理复杂的正则表达式

如果要匹配的文本模式很简单,正则表达式就很好。但匹配复杂的文本模式,可能需要长的、费解的正则表达式。你可以告诉re.compile() ,忽略正则表达式字符串中的空白符和注释,从而缓解这一点。要实现这种详细模式,可以向re.compile()传入变量re.VERBOSE,作为第二个参数。

现在,不必使用这样难以阅读的正则表达式:

python
phoneRegex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}
(\s*(ext|x|ext.)\s*\d{2,5})?)')

你可以将正则表达式放在多行中,并加上注释,像这样:

python
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)

请注意,前面的例子使用了三重引号('"),创建了一个多行字符串。这样就可以将正则表达式定义放在多行中,让它更可读。

正则表达式字符串中的注释规则,与普通的Python代码一样:# 符号和它后面直到行末的内容,都被忽略。而且,表示正则表达式的多行字符串中,多余的空白字符也不认为是要匹配的文本模式的一部分。这让你能够组织正则表达式,让它更可读。