Python自学笔记-第9章正则表达式

十年热恋 提交于 2020-08-19 21:56:08

正则表达式用于搜索,替换和解析字符串。使用正则表达式需要遵循一定的语法规则,用来编写一些逻辑验证非常方便,例如电子邮件的验证,Python提供了re模块实现正则表达式的验证。

 

1.简介

正则表达式是用于文本匹配的工具,在源字符串中查找与给定的正则表达式相匹配的部分。一个正则表达式是由字母,数字和特殊字符串(括号,星号,问号等)组成。

 

1.1.正则表达式中的特殊字符

 
符号 说明
^ 正则表达式的开始字符
$ 正则表达式的结束字符
\w 匹配字母,数字,下划线
\W 匹配不是字母,数字,下划线的字符
\s 匹配空白字符
\S 匹配不是空白字符
\d 匹配数字
\D 匹配非数字的字符
\b 匹配单词的开始和结束
\B 匹配不是单词开始和结束的位置
. 匹配任意字符,包括汉字
[m] 匹配单个字符串
[m1m2...n] 匹配多个字符串
[m-n] 匹配m到n区间的数字,字母
[^m] 匹配除m以外的字符串
() 对正则表达式进行分组,一对圆括号表示一组
 

正则表达式作为一门小型的语言,还提供了堆表达式的一部分进行重复处理的功能。

 

1.2.正则表达式中的常用限定符

 
符号 说明
* 匹配0次或多次
+ 匹配一次或多次
? 匹配一次或0次
{m} 重复m次
{m,n} 重复m到n次。其中n可以省略,表示m到任意次
 

默认情况下,正则表达式将匹配最长的字符串作为结果。可以通过在限定字符后面添加?的方式,获取最短匹配的结果。

 

1.3.限定符与"?"的组合

 
符号 说明
*? 匹配0次或多次,且最短匹配
+? 匹配一次或多次,且最短匹配
?? 匹配1次或0次,且最短匹配
{m,n}? 重复m次,且最短匹配
(? #...) 正则表达式中的注释
(? P<name>...) 给分组命名,name表示分组的名称
(? P =name) 使用名为name的分组
 

注:

  1. 表中(? P<name>...)(? P =name)是Python中的写法,其他的符号在各种编程语言中都是通用的。
 
  1. 这种方式即为正则表达式的贪婪与非贪婪模式,具体详解请看其他文章介绍。正则表达式之 贪婪与非贪婪模式详解
 

2.re模块

Python的re模块具有正则表达式匹配的功能。re模块提供了一些根据正则表达式进行查找,替换,分隔字符串的函数,这些函数使用一个正则表达式作为第一个参数。

 

2.1.re模块的常用函数

 
函数 说明
findall(pattern,string,flags=0) 根据pattern在string中匹配字符串。如果匹配成功,返回包含匹配结果的列表,否则返回空列表。当pattern中有分组时,返回包含多个元组的列表,每个元组对应1个分组。flags表示规则选项,规则选项用于辅助匹配
sub(pattern,repl,string,count=0) 根据指定的正则表达式替换源字符串中的子串。pattern是一个正则表达式,repl是用于替换的字符串,string是源字符串。如果count=0,则返回string中匹配的所有结果;如果count大于0,则返回前count个匹配结果。
subn(pattern,repl,string,count=0) 作用和sub()相同,返回1个2元的元组。第1个元素是替换结果,第2个元素是Ithink的次数
match(pattern,string,flags=0) 根据pattern从string的头部开始匹配字符串,只返回第1次匹配成的对象。否则返回None
search(pattern,string,flags=0) 根据pattern在string中匹配字符串,只返回第1次匹配成功的对象。如果匹配失败,返回None
compile(pattern,string,flags=0) 编译正则表达式,返回一个Pattern对象
split(pattern,string,maxsplit=0) 根据pattern分隔string,maxsplit表示最大的分隔数
escape(pattern) 匹配字符串中的特殊字符,如果 +,* ,? 等
 

flags参数的选项规则如下:

选项 说明
I或IGNORECASE 忽略大小写
L或LOCALE 字符集本地化,用于多语言环境
M或MULTILINE 多行匹配,使^$匹配除了string开始结束外,还匹配一行的开始和结束
S或DOTALL 使"."匹配包括\n在内的所有字符
X或VERBOSE 忽略正则表达式中的空白,换行,以方便添加注释
U或UNICODE "\w","\W","\b","\B","\d","\D","\s"和"\S"都将使用Unicode
In [1]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.findall("<div>.*</div>",y_str)
p
Out[1]:
['<div>test1</div>bb<div>test2</div>']
 

非贪婪模式

In [2]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.findall("<div>.*?</div>",y_str)
p
Out[2]:
['<div>test1</div>', '<div>test2</div>']
In [3]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.sub("<div>.*?</div>",'ww',y_str)
p
Out[3]:
'aawwbbwwcc'
In [4]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.subn("<div>.*?</div>",'ww',y_str)
p
Out[4]:
('aawwbbwwcc', 2)
 

match是从头开始匹配,所以如果用原正则表达式,则会返回None

In [12]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.match("<div>.*?</div>",y_str)
print(p)
 
None
In [11]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.match("aa<div>.*?</div>",y_str)
print(p.group(0))
 
aa<div>test1</div>
 

search与match不同点,则是不从头匹配

In [14]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
p = re.search("<div>.*?</div>",y_str)
print(p.group(0))
 
<div>test1</div>
 

2.2.Pattern对象

 

如果要多次使用同一规则匹配字符串,可以使用complile()函数进行预编译,compile函数返回1个pattern对象。该对象拥有一系列方法用于查找,替换或扩展字符串。

 
方法 说明
Pattern 获取当前使用的正则表达式
findall(string[,start[,end]]) 查找所有符合pattern对象匹配条件的结果,返回一个包含匹配结果的列表。参数string表示待查找的源字符串,参数start表示搜索开始的位置,参数end表示搜索结束的位置。
finditer(string[,start[,end]]) 返回一个包含匹配结果的地址
match(string[,start[,end]]) 同re.match
search(string[,start[,end]]) 同re.search
In [16]:
import re
y_str="aa<div>test1</div>bb<div>test2</div>cc"
pr = re.compile('<div>.*?</div>')
p = pr.search(y_str)
print(p.group(0))
 
<div>test1</div>
 

函数compile()通常与march(),search(),group()一起私用,对含有分组的正则表达式进行解析。正则表达式的分组从左往右开始计数,第1个出现的圆括号标记为第1组,依次类推。此外还有0组,用于存储匹配整个正则表达式的结果。

 

2.3.Match对象

 

match()和search()将返回1个match对象,match对象提供了一系列的方法和属性来管理匹配的结果。

 
属性和方法 说明
Pos 搜索的开始位置
Endpos 搜索的结束位置
String 搜索的字符串
Re 当前使用的正则表达式的对象
Lastindex 最后匹配的组索引
Lastgroup 最后匹配的组名
group(index=0) 某个分组的匹配结果。如果index=0,表示匹配整个正则表达式
groups() 所有分组的匹配结果,每个分组的结果组成1个列表返回
groupdict() 返回组名作为key,每个分组的匹配结果作为value的字典
start([group]) 获取组的开始位置
end([group]) 获取组的结束位置
span([group]) 获取组的开始和结束位置
expand(template) 使用组的匹配结果来替换模板template中的内容,并把替换后的字符串返回
In [24]:
import re
p = re.compile(r'(abc)\1')
m = p.match('abcabcabc')
print(m.groups())
print(m.group(0))
print(m.group(1))
 
('abc',)
abcabc
abc
In [28]:
p = re.compile(r"(?P<one>abc)(?P=one)")
m = p.search("abcabcabc")
print(m.group("one"))
print(m.groups())
print(m.groupdict())
 
abc
('abc',)
{'one': 'abc'}

更多文章,请关注:
          

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!