re 模块
正则表达式是一种技术,不仅是在 python、java、go 等编程语言中可以使用,在很多的软件中也支持。
python 中最常用的方式,就是 re
模块。
re.findall
搜索字符串,以列表形式返回所有匹配结果
import re
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)
运行结果:
['9999', '7890', '12345']
re.search
re.search 扫描整个字符串,并返回第一个成功的匹配
import re
ret = re.search('\d+', ' 540775360@qq.com')
ret.group()
运行结果:
540775360
re.match
re.match 从字符串的起始位置匹配一个模式,起始位置匹配不成功就返回 None
import re
result = re.match('\d+', ' 540775360@qq.com')
print(result)
print(result.group())
print(result.span())
re.sub
替换字符串中每一个匹配的字串,并返回替换后的结果
re.sub("正则表达式规则", "匹配到之后进行的处理", "需要从那个字符串里面匹配")
需求:将匹配到的阅读次数加 1
方法1:
# coding=utf-8
import re
ret = re.sub(r"\d+", '998', "python = 997")
print(ret)
运行结果:
python = 998
案例2:将 QQ 中间四位替换为 *
影藏。
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
将正则表达式字符串编译成正则对象,以便于复用该模式
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]
匹配不在方括号内的任意字符。
不区分大小写的匹配
通常,正则表达式用你指定的大小写匹配文本。例如,下面的正则表达式匹配完全不同的字符串:
regex1 = re.compile('RoboCop')
regex2 = re.compile('ROBOCOP')
regex3 = re.compile('robOcop')
regex4 = re.compile('RobocOp')
但是,有时候你只关心匹配字母,不关心它们是大写或小写。要让正则表达式不区分大小写,可以向re.compile() 传入 re.IGNORECASE
或 re.I
,作为第二个参数。在交互式环境中输入以下代码:
>>> 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,作为第二个参数。
现在,不必使用这样难以阅读的正则表达式:
phoneRegex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}
(\s*(ext|x|ext.)\s*\d{2,5})?)')
你可以将正则表达式放在多行中,并加上注释,像这样:
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代码一样:#
符号和它后面直到行末的内容,都被忽略。而且,表示正则表达式的多行字符串中,多余的空白字符也不认为是要匹配的文本模式的一部分。这让你能够组织正则表达式,让它更可读。