文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python re模块

2023-01-30 21:58

关注

正则表达式(可以称为REs,regex,regex pattens)是一个小巧的,高度专业化的编程语言,它内嵌于python开发语言中,可通过re模块使用。正则表达式的pattern可以被编译成一系列的字节码,然后用C编写的引擎执行。


常用正则表达式符号,基本上,包含了90%的场景。

'.'默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'匹配前一个字符1次或0次
'{m}'匹配前一个字符m次
'{n,m}'匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)'分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
'\A'只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'匹配字符结尾,同$
'\d'匹配数字0-9
'\D'匹配非数字
'\w'匹配[A-Za-z0-9]
'\W'匹配非[A-Za-z0-9]
's'匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
'(?P<name>...)'分组匹配

最常用的匹配语法

re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splita 以匹配到的字符当做列表分隔符
re.sub      匹配字符并替换

反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

举个列子:

匹配以Chen开头的字符串

import re
result = re.match("^Chen","ChenLong")
print(result)

执行输出

_sre.SRE_Match object; span=(0, 4), match='Chen'

结果是一个匹配对象,请注意结尾的match='Chen' 表示匹配出了Chen

如果没有匹配上,结果为None


打印匹配结果,使用group()方法查看

print(result.group())

执行输出 Chen

注意:如果没有匹配上,使用group()会报错。


上面的正则匹配规写死了,比如^Chen 这种需求,用in方法就可以实现了。

下面说一个简单的例子

匹配以Chen开头的以及后面的数字

import re
result = re.match("^Chen\d","Chen356Long")
print(result.group())

执行输出

Chen3


注意:

\d 表示匹配一个数字

如果想要匹配多个数字,使用\d+

import re
result = re.match("^Chen\d+","Chen356Long")
print(result.group())

执行输出

Chen356


匹配任意字符.+

res = re.match(".+","Chen321Long123")
print(res.group())

执行输出

Chen321Long123


匹配单个字符.

res = re.match(".","Chen321Long123")
print(res.group())

执行输出: C


匹配Long

res = re.match("^L.+g","Chen321Long123")
print(res)

执行输出: None

为什么呢?因为match是从左至右匹配,由于Long在字符串的中间,写任何正则都无法匹配出Long。

需要用到另外一个方法search,表示从整个文本中去搜索。结果只会返回一次,如果有多个结果,会返回第一个结果。

res = re.search("L.+g","Chen321Long123")
print(res.group())

执行输出: Long


如果使用L.+g$ 是匹配不到Long的,为什么呢?

$表示匹配整个字符串的结尾,而结尾是3。由于123不是我想要的,所以不能写g$


由于.+是匹配任意字符,如果只想匹配字母呢?使用[a-z]

res = re.search("L[a-z]+g","Chen321Long123")

匹配所有字母大小写呢?使用[a-zA-Z]

res = re.search("L[a-zA-Z]+g","Chen321Long123")


匹配jack

res = re.search("[a-z]+k","123#tom#jack#rose")
print(res)

执行输出:

_sre.SRE_Match object; span=(8, 12), match='jack'


'?' 匹配前一个字符1次或0次

匹配字母a

res = re.search("a?","alin")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 1), match='a'


匹配字母a

res = re.search("a?","lina")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 0), match=''

结果显示没有匹配上,请注意,? 可以匹配0次,也就是不匹配的情况。所以它的结果不是None


'?' 匹配前一个字符1次或0次


匹配aa或者aaa

res = re.search("aaa?","aalinaaa")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 2), match='aa'


请注意aaa? 需要拆分一下aa和aaa? 为什么呢? '?'是匹配0次或者1次数

aaa?匹配0次就是aa,匹配1次,就是aaa?


'{m}' 匹配前一个字符m次

匹配3个数字

res = re.search("[0-9]{3}","aa1x2a345aa")
print(res)

执行输出:

_sre.SRE_Match object; span=(6, 9), match='345'


匹配1到3次

res = re.search("[0-9]{1,3}","aa1x2a345aa")
print(res)

执行输出:

_sre.SRE_Match object; span=(2, 3), match='1'


匹配所有数字

res = re.search("[0-9]+","aa1x2a345aa")
print(res)

执行输出:

_sre.SRE_Match object; span=(2, 3), match='1'


为什么只有一个1呢?因为search只会返回一个结果,后续的不再返回。这个时候,需要用到findall方法

注意:findall没有group()方法

res = re.findall("[0-9]+","aa1x2a345aa")
print(res)

执行输出:

['1', '2', '345']


所有的数字,都匹配出来了。


只匹配第3次的结果

res = re.findall("[0-9]{3}","aa1x2a345aa")
print(res)

执行输出:

['345']


'|' 匹配|左或|右的字符


匹配abc或者ABC

res = re.findall("abc|ABC","ABCBabcCD")
print(res)

执行输出:

['ABC', 'abc']


'(...)'分组匹配


匹配abc,在匹配c 2次

res = re.search("abc{2}","xiabccc")
print(res)

执行输出:

_sre.SRE_Match object; span=(2, 6), match='abcc'


复杂的例子

匹配abc 2次,匹配||= 2次。注意:\| 转义了,表示|

res = re.search("(abc){2}(\|\|=){2}","abcabc||=||=")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 12), match='abcabc||=||='


'\A'只从字符开头匹配

'\Z'匹配字符结尾,同$


'\A' 效果和'^' 是一样的。


匹配以数字开头,字母结尾

res = re.search("\A[0-9]+[a-z]\Z","123a")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 4), match='123a'


'\d' 匹配数字

res = re.search("\A\d+[a-z]\Z","123a")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 4), match='123a'


'\D' 匹配非数字

匹配非数字

res = re.search("\D+","123a$ -\n")
print(res)

执行输出:

_sre.SRE_Match object; span=(3, 8), match='a$ -\n'


'\w'匹配[A-Za-z0-9]

res = re.search("\w+","1dF23$- \r\na")
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 5), match='1dF23'


'\W'匹配非[A-Za-z0-9]

res = re.search("\W+","1dF23$- \r\na")
print(res)

执行输出:

_sre.SRE_Match object; span=(5, 10), match='$- \r\n'


's'匹配空白字符、\t、\n、\r

res = re.search("\s+","1dF23$- \r\na")
print(res)

执行输出:

_sre.SRE_Match object; span=(7, 10), match=' \r\n'


'(?P<name>...)' 分组匹配 


组名为id,匹配数字

res = re.search("(?P<id>[0-9]+)","abcd1234daf@34")
#使用groupdict()方法打印组名
print(res.groupdict())

执行输出:

{'id': '1234'}


再添加一个分组name,匹配字母大小写

res = re.search("(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)","abcd1234daf@34")
print(res.groupdict())

执行输出:

{'name': 'daf', 'id': '1234'}

返回的结果是一个字典,如果想取值的话,使用如下方法:

res = re.search("(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)","abcd1234daf@34")
print(res.groupdict())
#第一种方法,直接传值
print(res.group("id"))
#第二种方法,用字典的方式
print(res.groupdict()['name'])

执行输出:

{'id': '1234', 'name': 'daf'}

1234

daf


举个复杂的例子

身份证号,前2位是省,再后面2位是市,再后面2位是区,再后面8位是出生日期

res = re.search("(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<area>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
print(res)

执行输出:

{'birthday': '1993', 'city': '14', 'province': '37', 'area': '81'}


re.split 以匹配到的字符当做列表分隔符


res = re.split("[0-9]","abc12de3f45GH")
print(res)

执行输出:

['abc', 'de', 'f', 'GH']


re.sub   匹配字符并替换

res = re.sub("[0-9]+","|","abc12de3f45GH")
print(res)

执行输出:

abc|de|f|GH


只替换一个

res = re.sub("[0-9]+","|","abc12de3f45GH",count=1)
print(res)

执行输出:

abc|de3f45GH


仅需轻轻知道的几个匹配模式

re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上面)
S(DOTALL): 点任意匹配模式,改变'.'的行为


忽略大小写

res = re.search("[a-z]+","abcA",flags=re.I)
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 4), match='abcA'


res = re.search(r"^a","\nabc\neee",flags=re.M)
print(res)

执行输出:

_sre.SRE_Match object; span=(1, 2), match='a'


匹配任意字符

res = re.search(r".+","\nabc\neee",flags=re.S)
print(res)

执行输出:

_sre.SRE_Match object; span=(0, 8), match='\nabc\neee'



阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯