Python正则表达式re模块简明笔记文档格式.docx
《Python正则表达式re模块简明笔记文档格式.docx》由会员分享,可在线阅读,更多相关《Python正则表达式re模块简明笔记文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
因此,当你不指定pos和endpos时,match方法默认匹配字符串的头部。
当匹配成功时,返回一个Match对象,如果没有匹配上,则返回None。
看看例子。
>
importre
pattern=pile(r'
)
#用于匹配至少一个数字
m=pattern.match('
one12twothree34four'
#查找头部,没有匹配
printm
None
2,10)#从'
e'
的位置开始匹配,没有匹配
3,10)#从'
1'
的位置开始匹配,正好匹配
printm
#返回一个Match对象
<
_sre.SRE_Matchobjectat0x10a42aac0>
m.group(0)
#可省略0
'
12'
m.start(0)
3
m.end(0)
5
m.span(0)
(3,5)
在上面,当匹配成功时返回一个Match对象,其中:
∙group([group1,…])
方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用
group()
或
group(0);
∙start([group])
方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为0;
∙end([group])
方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为0;
∙span([group])
方法返回
(start(group),end(group))。
再看看一个例子:
([a-z]+)([a-z]+)'
re.I)
#re.I表示忽略大小写
HelloWorldWideWeb'
#匹配成功,返回一个Match对象
_sre.SRE_Matchobjectat0x10bea83e8>
#返回匹配成功的整个子串
HelloWorld'
#返回匹配成功的整个子串的索引
(0,11)
m.group
(1)
#返回第一个分组匹配成功的子串
Hello'
m.span
(1)
#返回第一个分组匹配成功的子串的索引
(0,5)
m.group
(2)
#返回第二个分组匹配成功的子串
World'
m.span
(2)
(6,11)
m.groups()
#等价于(m.group
(1),m.group
(2),...)
('
'
m.group(3)
#不存在第三个分组
Traceback(mostrecentcalllast):
File"
stdin>
"
line1,in<
module>
IndexError:
nosuchgroup
search方法
search方法用于查找字符串的任何位置,它也是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果,它的一般使用形式如下:
search(string[,pos[,endpos]])
让我们看看例子:
pattern=pile('
m=pattern.search('
#这里如果使用match方法则不匹配
m
_sre.SRE_Matchobjectat0x10cc03ac0>
m.group()
10,30)
#指定字符串区间
_sre.SRE_Matchobjectat0x10cc03b28>
34'
m.span()
(13,15)
再来看一个例子:
#-*-coding:
utf-8-*-
#将正则表达式编译成Pattern对象
#使用search()查找匹配的子串,不存在匹配的子串时将返回None
#这里使用match()无法成功匹配
m=pattern.search('
hello123456789'
ifm:
#使用Match获得分组信息
print'
matchingstring:
m.group()
position:
m.span()
执行结果:
123456
(6,12)
findall方法
上面的match和search方法都是一次匹配,只要找到了一个匹配的结果就返回。
然而,在大多数时候,我们需要搜索整个字符串,获得所有匹配的结果。
findall方法的使用形式如下:
findall(string[,pos[,endpos]])
findall以列表形式返回全部能匹配的子串,如果没有匹配,则返回一个空列表。
看看例子:
#查找数字
result1=pattern.findall('
result2=pattern.findall('
one1two2three3four4'
0,10)
printresult1
printresult2
['
123456'
789'
]
2'
finditer方法
finditer方法的行为跟findall的行为类似,也是搜索整个字符串,获得所有匹配的结果。
但它返回一个顺序访问每一个匹配结果(Match对象)的迭代器。
result_iter1=pattern.finditer('
result_iter2=pattern.finditer('
printtype(result_iter1)
printtype(result_iter2)
print'
result1...'
form1inresult_iter1:
#m1是Match对象
{},position:
{}'
.format(m1.group(),m1.span())
result2...'
form2inresult_iter2:
.format(m2.group(),m2.span())
type'
callable-iterator'
type'
result1...
123456,position:
789,position:
(13,16)
result2...
1,position:
(3,4)
2,position:
(7,8)
split方法
split方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
split(string[,maxsplit])
其中,maxsplit用于指定最大分割次数,不指定将全部分割。
p=pile(r'
[\s\,\;
]+'
printp.split('
a,b;
;
c
d'
a'
b'
c'
d'
sub方法
sub方法用于替换。
它的使用形式如下:
sub(repl,string[,count])
其中,repl可以是字符串也可以是一个函数:
∙如果repl是字符串,则会使用repl去替换字符串每一个匹配的子串,并返回替换后的字符串,另外,repl还可以使用
\id
的形式来引用分组,但不能使用编号0;
∙如果repl是函数,这个方法应当只接受一个参数(Match对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。
count用于指定最多替换次数,不指定时全部替换。
(\w+)(\w+)'
s='
hello123,hello456'
deffunc(m):
return'
hi'
+'
'
+m.group
(2)
printp.sub(r'
helloworld'
s)
#使用'
替换'
hello123'
和'
hello456'
\2\1'
#引用分组
printp.sub(func,s)
printp.sub(func,s,1)
#最多替换一次
helloworld,helloworld
123hello,456hello
hi123,hi456
hi123,hello456
subn方法
subn方法跟sub方法的行为类似,也用于替换。
subn(repl,string[,count])
它返回一个元组:
(sub(repl,string[,count]),替换次数)
元组有两个元素,第一个元素是使用sub方法的结果,第二个元素返回原字符串被替换的次数。
printp.subn(r'
s)
printp.subn(func,s)
printp.subn(func,s,1)
helloworld,helloworld'
2)
123hello,456hello'
hi123,hi456'
hi123,hello456'
1)
其他函数
事实上,使用compile函数生成的Pattern对象的一系列方法跟re模块的多数函数是对应的,但在使用上有细微差别。
match函数
match函数的使用形式如下:
re.match(pattern,string[,flags]):
其中,pattern是正则表达式的字符串形式,比如
\d+,
[a-z]+。
而Pattern对象的match方法使用形式是:
可以看到,match函数不能指定字符串的区间,它只能搜索头部,看看例子:
m1=re.match(r'
One12twothree34four'
ifm1:
m1.group()
else:
m1is:
m1
m2=re.match(r'
12twothree34four'
ifm2:
m2.group()
m2is:
m2
None
12
search函数
search函数的使用形式如下:
re.search(pattern,string[,flags])
search函数不能指定字符串的搜索区间,用法跟Pattern对象的search方法类似。
findall函数
findall函数的使用形式如下:
re.findall(pattern,string[,flags])
findall函数不能指定字符串的搜索区间,用法跟Pattern对象的findall方法类似。
printre.findall(r'
hello12345789'
#输出
12345'
finditer函数
finditer函数的使用方法跟Pattern的finditer方法类似,形式如下:
re.finditer(pattern,string[,flags])
split函数
split函数的使用形式如下:
re.split(pattern,string[,maxsplit])
sub函数
sub函数的使用形式如下:
re.sub(pattern,repl,string[,count])
subn函数
subn函数的使用形式如下:
re.subn(pattern,repl,string[,count])
到底用哪种方式
从上文可以看到,使用re模块有两种方式:
∙使用pile函数生成一个Pattern对象,然后使用Pattern对象的一系列方法对文本进行匹配查找;
∙直接使用re.match,re.search和re.findall等函数直接对文本匹配查找;
下面,我们用一个例子展示这两种方法。
先看第1种用法:
#将正则表达式先编译成Pattern对象
printpattern.match('
123,123'
printpattern.search('
234,234'
printpattern.findall('
345,345'
再看第2种用法:
printre.match(r'
printre.search(r'
如果一个正则表达式需要用到多次(比如上面的
\d+),在多种场合经常需要被用到,出于效率的考虑,我们应该预先编译该正则表达式,生成一个Pattern对象,再使用该对象的一系列方法对需要匹配的文件进行匹配;
而如果直接使用re.match,re.search等函数,每次传入一个正则表达式,它都会被编译一次,效率就会大打折扣。
因此,我们推荐使用第1种用法。
匹配中文
在某些情况下,我们想匹配文本中的汉字,有一点需要注意的是,中文的unicode编码范围
主要在
[\u4e00-\u9fa5],这里说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的。
假设现在想把字符串
title=u'
你好,hello,世界'
中的中文提取出来,可以这么做:
pattern=pile(ur'
[\u4e00-\u9fa5]+'
result=pattern.findall(title)
printresult
注意到,我们在正则表达式前面加上了两个前缀
ur,其中
r
表示使用原始字符串,u
表示是unicode字符串。
执行结果:
[u'
\u4f60\u597d'
u'
\u4e16\u754c'
贪婪匹配
在Python中,正则匹配默认是贪婪匹配(在少数语言中可能是非贪婪),也就是匹配尽可能多的字符。
比如,我们想找出字符串中的所有
div
块:
content='
aa<
div>
test1<
/div>
bb<
test2<
cc'
.*<
result=pattern.findall(content)
由于正则匹配是贪婪匹配,也就是尽可能多的匹配,因此,在成功匹配到第一个
时,它还会向右尝试匹配,查看是否还有更长的可以成功匹配的子串。
如果我们想非贪婪匹配,可以加一个
?
,如下:
.*?
#加上?
结果:
小结
∙使用compile函数将正则表达式的字符串形式编译为一个Pattern对象;
∙通过Pattern对象提供的一系列方法对文本进行匹配查找,获得匹配结果(一个Match对象);
∙最后使用Match对象提供的属性和方法获得信息,根据需要进行其他的操作;
Python的正则匹配默认是贪婪匹配。
【编辑推荐】
1.干货分享:
Python开发的高级技巧
2.Python内存问题:
提示和技巧
3.盘点十大隐藏在Python中的彩蛋
4.Python爬虫爬取美剧网站
5.Python程序员都该用的一个库