python re正则常用函数和模式pattern的书写规则与限制方法 看完百分之百学会python正则

re的常用函数

re.search()和re.match()

re.search()和re.match()一样,参数都是(pattern, str),但区别是re.match()只从头开始匹配,re.search()搜索整个字符串。

但我都能搜索整个字符串了,我还用match干什么呢。也许你会说效率云云,也有一定道理,但都用python代码了我还那么关心效率干什么呢。总之我是只用search的。

import re
pattern = 'dog'
m1 = re.match(pattern, "I'm not dog")
m2 = re.search(pattern, "I'm not dog")
print(m1)
print(m2)

result:
None
<re.Match object; span=(8, 11), match='dog'>

结果为match没有匹配上,search成功找到了

另外,如果不指定,search只会寻找第一个符合要求的内容

import re
pattern = 'dog'
m = re.search(pattern, "I'm not black dog but white dog")
print(m)

result:
<re.Match object; span=(14, 17), match='dog'>

可以看到search的结果还需要进一步加工,如果需要知道位置和内容,使用span和group即可

import re
pattern = 'dog'
m = re.search(pattern, "I'm not black dog but white dog")
print(m.span())
print(m.group())

result:
(14, 17)
dog

re.findall()

在不调整pattern的情况下,search只能找到字符串中最靠前的目标,为了找到所有目标,可以使用findall()函数

import re
pattern = 'dog'
m = re.findall(pattern, "I'm not black dog but white dog")
print(m)

result:
['dog', 'dog']

findall也可以指定字符串起始位置和终止位置,但需要改写一下方式

import re
p = 'dog'
pattern = re.compile(p)
m = pattern.findall("I'm not black dog but white dog", 13, 20)
print(m)

result:
['dog']

re.sub()

sub()可以用来替换找到的目标,参数为(pattern, repl, string, count)
repl可以为替换目标,也可以为函数,需要入参,参数为match,也需要return回东西;
count是替换次数,默认数量0,即全部替换

import re


def cat(match):
    print(match)
    return 'cat'


m = re.sub("dog", cat, "I'm not black dog but white dog")
print(m)

result:
<re.Match object; span=(14, 17), match='dog'>
<re.Match object; span=(28, 31), match='dog'>
I'm not black cat but white cat

pattern书写规则

定位的符号

如果我不喜欢黑毛,只喜欢白毛,只想定位white dog,就可以使用括号突出我需要定位的目标,并在周围填写目标周围的信息即可实现定位

import re
pattern = "white (dog)"
m = re.search(pattern, "I'm not black dog but white dog")
print(m)
print(m.group(0))
print(m.group(1))

result:
<re.Match object; span=(22, 31), match='white dog'>
white dog
dog

但我又改变主意了,我突然又喜欢黑毛了,我两个都想定位,此时需要使用两个括号即可

import re
pattern = "black (dog) but white (dog)"
m = re.search(pattern, "I'm not black dog but white dog")
print(m)
print(m.group(0))
print(m.group(1))
print(m.group(2))

result:
<re.Match object; span=(8, 31), match='black dog but white dog'>
black dog but white dog
dog
dog

可以看到group的参数是递增的,第几个括号填几就可以了

定位模糊信息

假如我就是喜欢白毛,是不是狗都无所谓,便可以将括号中的内容正则化,.指代单个非回车的字符,*代表任意多,两者组合起来便可代表任意长度的字符串,其他表示方法后面介绍

import re
pattern = "white (.*)!"
m = re.search(pattern, "I'm not black dog but white dog!")
print(m)
print(m.group(0))
print(m.group(1))

result:
<re.Match object; span=(22, 32), match='white dog!'>
white dog!
dog

限制

最短匹配和贪婪匹配

看这样一个例子:

import re
pattern = "white (.*)!"
m = re.search(pattern, "I'm not black dog but white dog!I don't like black dogs!")
print(m)
print(m.group(0))
print(m.group(1))

result:
<re.Match object; span=(22, 55), match="white dog!I don't like black dogs!">
white dog!I don't like black dogs!
dog!I don't like black dogs

可以看到white和!直接有两组,一组短一组长,如果不作指定,一定会返回最长的那组,这种匹配方式叫做贪婪匹配。

如果想要匹配最短的一组,需要加上问号,注意不要加错地方

import re
pattern = "white (.*?)!"
m = re.search(pattern, "I'm not black dog but white dog!I don't like black dogs!")
print(m)
print(m.group(0))
print(m.group(1))

result:
<re.Match object; span=(22, 32), match='white dog!'>
white dog!
dog

长度限制

使用{},具体后面讲

正确书写你的匹配模式

前面讲过,匹配任意字符串需要用到.*的模式,只要掌握如何确定字符集和数量,基本就可以熟练使用正则了

确定你的字符集

字符作用
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
^匹配字符串的开头
$匹配字符串的末尾。

举个简单的例子

import re
pattern = "^(.*)$"
m = re.search(pattern, "I'm not black dog but white dog!")
print(m)
print(m.group())

result:
<re.Match object; span=(0, 32), match="I'm not black dog but white dog!">
I'm not black dog but white dog!

这就从头到尾全部拿下来了

如果要指定字符集,则需要使用中括号[],示例中只匹配由只包含d,o,g三种及以下种类字符的字符串,需要注意的是,中括号中的字符种类虽然多,但他在数量上只代表一个字符

import re
pattern = ".* ([god]*) .*"
m = re.findall(pattern, "I'm not black dog but white dogs!")
print(m)

result:
['dog']

如果不想匹配到包含某些字符的字符串,使用^就可以了

import re
pattern = " ([^t]*) "
m = re.findall(pattern, "I'm not black dog but white dogs!")
print(m)

result:
['black dog']

可以写在中括号里的符号如下:

符号含义
\d匹配一个数字字符。等价于 [0-9]
\D匹配一个非数字字符。等价于 [^0-9]
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
,n\w匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’
\W匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’

确定字符数量

数量字符控制前一个字符的匹配次数,这也是我刚才在强调[中括号]只代表一个字符的原因所在,含义表格如下:

字符含义
*匹配0次或1次或多次
+匹配1次或多次
?匹配0次或1次
{m}匹配m次,既不能多也不能少
{m,n}匹配[m,n]次,m,n可以有一边为空,但逗号得留下,即{m,}或{,n}
import re
pattern = "black ([dogs]{3}) .*"
m1 = re.findall(pattern, "I'm not black do but white dog!")
m2 = re.findall(pattern, "I'm not black dog but white dog!")
m3 = re.findall(pattern, "I'm not black dogs but white dog!")
print(m1)
print(m2)
print(m3)

result:
[]
['dog']
[]

可以看到,只有字符串长度正好是3时才可以匹配上,少于或多余都不可以。
如果写作{2,4}即可全部匹配

import re
pattern = "black ([dogs]{2,4}) .*"
m1 = re.findall(pattern, "I'm not black do but white dog!")
m2 = re.findall(pattern, "I'm not black dog but white dog!")
m3 = re.findall(pattern, "I'm not black dogs but white dog!")
print(m1)
print(m2)
print(m3)

result:
['do']
['dog']
['dogs']

暂时就写到这里吧,肝了三个小时,明天还得上班,哭哭
剩下诸如逻辑符或者命名之类乱七八糟的有时间以后再写吧,不过八成不会有以后了,上边写的这些差不多已经够用了

转载,注明,出处!阿里嘎多

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值