Python正则re模块详解

Cooking Regex微信公众号
正则表达式学习

 

目录

re.match

re.fullmatch 

re.search 

 re.sub

re.subn

re.split 

 re.findall

re.finditer 

 re.compile

 re.purge

 re.escape


阅读本文章时,已默认您对正则表达式有了一定的了解。该教程是对Python的re模块的介绍及注意点提示,希望对您有一定的帮助,如果有解释不到位的地方,还请各位朋友帮忙指出,大家一起进步。好了,那就让我们开始Python正则之旅吧!

 最好的学习资料是官方文档,那我们先来看下Python文档里面的介绍,我的版本是Python3.7.2

import re
help(re)

可以看到目前的Python版本re模块里面包含了以下几个正则相关的方法:

现在我们就按这个顺序来介绍下这几个方法。


re.match

根据官方的介绍,我们可以知道该方法有三个参数 :

  • pattern 表示传进来的正则表达式
  • string 表示被匹配的字符串
  • flags 正则表达式匹配的模式

如下,目前支持7种模式:

对应的中文解释

  • A  该模式会让正则表达式以ASCII字符集去匹配字符串,而不是以Unicode。主要影响的正则有
\w、\W、\d、\D、\b、\B
  • I  忽略大小写
  • L 该模式会使以下正则根据本地环境去匹配
\w、\W、\b、\B
  • M 多行模式匹配,影响^和$
  • S 会使.元字符匹配所有字符,包括换行符
  • X 忽略空白符和注释,主要用于书写正则的格式,添加注释等,为了更好的解释所写的正则
  • U 根据Unicode字符集匹配字符串

接下来,我们就用代码来验证该方法:

该方法是从字符串的起始位置开始匹配字符串。如果匹配上,则会返回一个对象,否则返回None

来看两个例子,你就明白了

demo1

import re
result=re.match(r"\d+","abc123")
print(result)

结果如下:

None

 demo2

import re
result=re.match(r"\d+","123abc")
print(result)

 <re.Match object; span=(0, 3), match='123'>

看到这里,我想你应该明白re.match这个方法的用法了吧。后面我们会把该方法和re.search做比较。现在我们再来看看,返回的这个Match对象对应的类的一个介绍。

在这里可以看到,re.match()和re.search()返回的结果都是Match这个类的一个实例 对象

 下图是该类的几个比较常用的方法:


 

re.fullmatch 

 该方法需要整个字符串跟正则完全匹配才会返回一个Match对象,否则返回None

 demo1

import re
result=re.fullmatch(r"\d+","123abc")
print(result)

结果:

None

demo2

import re
result=re.fullmatch(r"\d+","123")
print(result)

 <re.Match object; span=(0, 3), match='123'>


 

re.search 

 该方法会根据传入的正则去扫描整个字符串,若能找到对应的子字符串,则返回该Match对象,否则返回None。这里返回的Match对象保存的是从左到右匹配到的第一个子字符串的信息。

demo1

import re
result=re.search(r"\d+","abc123")
print(result)

 <re.Match object; span=(3, 6), match='123'>

demo2

import re
result=re.search(r"\d+","abc1kkk")
print(result)

 <re.Match object; span=(3, 4), match='1'>

demo3

import re
result=re.search(r"\d+","abckkk")
print(result)

 None

 可以看到,re.match和re.search都是在字符串中查找字符串,但区别是

  • re.match 字符串的开始位置的字符串必须匹配该正则,否则返回None。你可以理解为startWith的意思
  • re.search 从左到右匹配,只要字符串中的任意一个子串能匹配到该正则,则返回匹配到的第一个子字符串的信息。你可以理解为包含的意思

来看几个等价的demo

import re
result=re.search(r"\A\d+","abc1kkk")
print(result)
result=re.match(r"\d+","abc1kkk")
print(result)
result=re.search(r"^\d+","abc1kkk")
print(result)

上面这几个代码的执行结果的一样的,代码所表示的含义也是一样的。寻找的是开头位置的数字

 re.sub

 这个方法的作用是字符串替换,其中,rep1可以是字符串,也可以是一个方法。

  • 当rep1是一个字符串时,里面的转义字符会被加工处理。这里怎么理解呢?也就是说,是特殊符号的,会被转为对应的意思,rep1里面的\n会被处理为换行符,\r会被处理成回车换行符,不确定的转义符不会处理,例如\&等。如果是向后引用的,则会替换成对应的引用组捕获的内容,例如,\1会被替换成group(1)的内容,\2会被替换成group(2)的内容。
  • 当rep1是一个方法时,该方法的入参是一个Match对象,并且必须有返回值

rep1为字符串时的例子如下:

 

import re
#在每个匹配结果前后加上-
result=re.sub(r"(\d+)",r"-\1-","abc1kk2k")
print(result)
#错误的写法,rep1前面没有加r
result=re.sub(r"(\d+)","-\1-","abc1kk2k")
print(result)

abc-1-kk-2-k
abc--kk--k

 结果分析,从结果上面可以看到,当rep1字符串前面没有加上r标识符的时候,里面的\1会被按特殊字符处理为它表示的意思,而加上r标识符之后,结果才是正常的。当然,你可以像下面这么写:

import re
result=re.sub(r"(\d+)","-\g<1>-","abc1kk2k")
print(result)
result=re.sub(r"(\d+)",r"-\g<1>-","abc1kk2k")
print(result)
result=re.sub(r"\d+",r"-\g<0>-","abc1kk2k")
print(result)
result=re.sub(r"\d+","-\g<0>-","abc1kk2k")
print(result)
result=re.sub(r"(?P<num>\d+)",r"-\g<num>-","abc1kk2k")
print(result)
result=re.sub(r"(?P<num>\d+)","-\g<num>-","abc1kk2k")
print(result)

那如果我们需要把匹配到的每个数字加1,要怎么写呢?这个时候就需要在rep1传入一个function方法了:

demo1

import re
def add(m):
    return str(int(m.group())+1)
result=re.sub(r"\d+",add,"abc1kk2k")
print(result)

demo2

import re
result=re.sub(r"\d+",lambda m:str(int(m.group())+1),"abc1kk2k")
print(result)

demo3

import re
result=re.sub(r"(?P<num>\d+)",lambda m:str(int(m.group("num"))+1),"abc1kk2k")
print(result)

re.subn

 该方法除了会多返回一个替换次数的结果外,其他功能都与sub一样。返回结果是一个tupl

import re
result=re.subn(r"(\d+)",r"-\1-","abc1kk2k4")
print(result)
result=re.sub(r"(\d+)",r"-\1-","abc1kk2k4")
print(result)

result=re.subn(r"(\d+)",r"-\1-","abc1kk2k4",2)
print(result)
result=re.sub(r"(\d+)",r"-\1-","abc1kk2k4",2)
print(result)

结果: 

('abc-1-kk-2-k-4-', 3)
abc-1-kk-2-k-4-
('abc-1-kk-2-k4', 2)
abc-1-kk-2-k4

re.split 

 如果pattern没有捕获组的话,则按照正则分割后,返回一个list结果集;如果pattern里面包含捕获组的话,list结果集里面包含捕获组获取到的内容

import re
result=re.split(r"\d+","abc11kk22k34")
print(result)
result=re.split(r"(\d+)","abc11kk22k34")
print(result)

result=re.split(r"\d+","abc11kk22k34",2)
print(result)
result=re.split(r"(\d+)","abc11kk22k34",2)
print(result)

['abc', 'kk', 'k', '']
['abc', '11', 'kk', '22', 'k', '34', '']
['abc', 'kk', 'k34']
['abc', '11', 'kk', '22', 'k34']

 re.findall

  •  pattern 没有捕获组的话,该方法会返回所有匹配结果的list
  • pattern 包含一个或多个捕获组的话,list保存的结果是这些捕获组的匹配结果,且list里面的各项都是一个tuples
import re
result=re.findall(r"[a-z]+\d+","abc11kk22k34")
print(result)
result=re.findall(r"[a-z]+(\d+)","abc11kk22k34")
print(result)
result=re.findall(r"([a-z]+)(\d+)","abc11kk22k34")
print(result)
result=re.findall(r"([a-z]+)(\d+)()()()","abc11kk22k34")
print(result)

['abc11', 'kk22', 'k34']
['11', '22', '34']
[('abc', '11'), ('kk', '22'), ('k', '34')]
[('abc', '11', '', '', ''), ('kk', '22', '', '', ''), ('k', '34', '', '', '')]

re.finditer 

 返回一个迭代器,迭代器里面的每个对象都是Match类型的数据

import re
result=re.finditer(r"\d+","abc11kk22k34")
for m in result:
    print(m.group(0))
print()
result=re.finditer(r"(\d+)","abc11kk22k34")
for m in result:
    print(m.group(0))
    print(m.group(1))

 re.compile

编译正则,返回一个Pattern对象。 这样做的目的是可以重复使用该正则模式对象

 

该Pattern类有如下方法

 re.purge

 清除正则表达式缓存

 re.escape

 转义特殊字符,就是把有特殊意义的字符串转义为普通字符串

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值