正则表达式用于搜索,替换和解析字符串。使用正则表达式需要遵循一定的语法规则,用来编写一些逻辑验证非常方便,例如电子邮件的验证,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的分组 |
注:
- 表中
(? P<name>...)和(? P =name)是Python中的写法,其他的符号在各种编程语言中都是通用的。
- 这种方式即为正则表达式的贪婪与非贪婪模式,具体详解请看其他文章介绍。正则表达式之 贪婪与非贪婪模式详解
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'}
更多文章,请关注:
来源:oschina
链接:https://my.oschina.net/u/3275937/blog/4282155