re模块
在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤⼀个python自带的模块,名字为re。
引子
有如下数据,如果想找到所有电话,如下代码可以实现
1 张三 15234558644
2 王二 13546125484
3 王五 12454554687
with open("新建 文本文档.txt", "r", encoding="utf-8") as f:
for line in f:
a, b, c = line.split()
if c.startswith("1"):
print(c)
想要更简便实现查找,此时就要用到re模块
import re
with open("新建 文本文档.txt", "r", encoding="utf-8") as f:
phone_list = re.findall("[0-9]{11}", f.read())
print(phone_list) # ['15234558644', '13546125484', '12454554687']
re的匹配语法
re匹配规则
示例
import re
# 匹配包含
res = re.search(".", "text") # <re.Match object; span=(0, 1), match='t'>
print(res.group()) # t
# 分组匹配
res = re.search("(abc){2}a(123|45)", "abcabca456c") # <re.Match object; span=(0, 9), match='abcabca45'>
print(res.group()) # abcabca45
# 匹配不到时返回None,此时不能.group()
res = re.search("(abc){3}a(123|45)", "abcabca456c") # None
print(res) # None
案例-身份证匹配
对于18位身份证
- 前六位数字表示地址码.例如,110101 代表北京市东城区。
- 第七位至十四位数字表示出生日期码
- 第十五位至十七位数字表示顺序码,它表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
- 第十八位数字是校验码,它是根据前面十七位数字码,按照 ISO 7064:1983.MOD 11-2 校验码计算出来的检验码。校验码的计算方法较为复杂,主要是为了验证身份证号码的合法性和准确性。
import re
my_id = "411282200412121122"
# 1.返回身份证号前10位
res = re.search("([0-9]{3})([0-9]{3})([0-9]{4})", my_id)
print(res.group()) # 4112822004
# 2.以元组方式返回
print(res.groups()) # ('411', '282', '2004')
# 3.以字典方式返回
res2 = re.search("(?P<province>[0-9]{3})(?P<city>[0-9]{3})(?P<year>[0-9]{4})", my_id)
print(res2.groupdict()) # {'province': '411', 'city': '282', 'year': '2004'}
# res2也可用1,2方式返回
print(res2.group()) # 4112822004
print(res.groups()) # ('411', '282', '2004')
示例2
import re
# \d匹配一个数字
print(re.search("\d", "12345").group()) # 1
# re.split()分隔
print(re.split("\d", "zhang2yi3zhuo")) # ['zhang', 'yi', 'zhuo']
print(re.split("\w", "zhang2yi3zhuo")) # ['', '', '', '', '', '', '', '', '', '', '', '', '', '']
# re.sub()替换
# 将"abc替换为"ABC",最多替换2次
print(re.sub("abc", "ABC", "abc123", count=2)) # ABC123
print(re.sub("abc", "ABC", "abcabcabc123", count=2)) # ABCABCabc123
# re.fullmatch()全部匹配(精确匹配)
# 需要全部一样才匹配成功
print(re.fullmatch("zhangyizhuo", "zhangyizhuo123")) # None
print(re.fullmatch("zhangyizhuo123", "zhangyizhuo123")) # <re.Match object; span=(0, 14), match='zhangyizhuo123'>
print(re.fullmatch("zhangyizhuo123", "zhangyizhuo123").group()) # zhangyizhuo123
# re.match()从头开始匹配
print(re.match("abc", "123abc")) # None
print(re.match("abc", "abc123")) # <re.Match object; span=(0, 3), match='abc'>
print(re.match("abc", "abc123").group()) # abc
re.compile & re.match
re.compile可以给正则表达式设置匹配模式,赋值给变量以便后续使用
import re
# re.compile()可以将定义好的匹配模式赋给一个变量
pattern = re.compile("\d{3}")
# 之后可以调用此匹配模式
print(re.match(pattern, "123abc456")) # <re.Match object; span=(0, 3), match='123'>
print(re.match(pattern, "123abc456").group()) # 123
Flags标志符
flags作为re.search(),re.match()等方法的第三个参数,可以扩展正则表达式的使用
import re
# re.I忽略大小写
print(re.search("abc", "Abc123")) # None
print(re.search("abc", "Abc123", re.I)) # <re.Match object; span=(0, 3), match='Abc'>
# re.M多行模式,改变'^'或'$'行为
print(re.search("^abc", "abc123")) # <re.Match object; span=(0, 3), match='abc'>
print(re.search("^abc", "aabc123")) # None
print(re.search("^abc", "a\nabc123")) # None
print(re.search("^abc", "a\nabc123", re.M)) # <re.Match object; span=(2, 5), match='abc'>
# re.S改变'.'的行为,使'.'也可以匹配\n
print(re.search(".{3}", "bc\n")) # None
print(re.search(".{3}", "bc\n", re.S)) # <re.Match object; span=(0, 3), match='bc\n'>
# re.X使得可以给表达式写注释,多用于复杂正则表达式中
# r""表示原始字符串(raw string):会让\变为普通字符,使其失去转义能力
pattern = re.compile(r"""
(\d{3}) # 匹配省份
(\d{3}) # 匹配市区
(\d{4}) # 匹配出生年
""", re.X)
print(re.match(pattern, "411282200412121122")) # <re.Match object; span=(0, 10), match='4112822004'>
print(re.match(pattern, "411282200412121122").group()) # 4112822004