最近用Python的正则表达式做了许多工作,参考了余晟的《正则指引》,收获颇多,在此一一记录:
1. 正则表达式的几种匹配方法:
有三种方法可以用来进行正则表达式的匹配:search,match,findall
(1) re.search(pattern,string[,flags])
其中pattern为正则表达式,string为待匹配的文本,flags为匹配模式(详细介绍请见(5)).
search方法用来测试正则表达式pattern能否在string中找到,如果可以则返回一个MatchObject对象,否则返回None。
MatchObject对象会在用search或match方法匹配成功时返回的结果,有很多有用的方法来分析匹配得到的结果:
方法名 | 作用 |
pos | 返回整个表达式匹配开始的位置 |
end | 返回整个表达式匹配结束的位置 |
start(n) | 返回第n个捕获分组匹配开始的位置,n默认为0 |
end(n) | 返回第n个捕获分组匹配结束的位置,n默认为0 |
group(n) | 返回第n个捕获分组匹配的文本,如果没有设定n则返回整个表达式匹配的文本,此时n为0 |
groups() | 返回各个捕获分组匹配的文本构成的元组(tuple),如果正则表达式中没有捕获分组,则返回空元组 |
所谓捕获分组亦即表达式中用括号括起来的表达式。正则表达式中经常会出现括号,所有括号括起来的部分都会被认为是捕获分组,如果不想让括号内表达式匹配的文本被捕获,则应该在左括号内加入?:符号。
注意,此处的group和groups比较容易混淆。group()不等同于groups(),因为group()返回的是整个表达式匹配的文本,而groups()则返回的是各个捕获分组匹配的文本构成的元组。
(2) re.match(pattern,string[,flags])
match方法从string文本的最左端开始尝试匹配正则表达式pattern,如果成功则返回MatchObject,否则返回None。注意,match方法并不能用户来进行验证,因为他并不保证pattern能够一直匹配到string的末尾,所以用match进行验证的话需要在正则表达式的末尾加上\Z符号。
(3) re.findall(pattern,string[,flags])
findall方法会一次性找出pattern在string中的所有的匹配,如果有匹配结果则返回一个包含所有匹配文本的列表,否则返回一个空列表。
2. 使用正则表达式进行替换
re.sub(pattern,replacement,string[,flags])
将string文本中的所有pattern能够匹配的文本都替换成replacement指定的文本。如果要在replacement字符串中引用之前某个分组捕获的文本,可以使用\num或者\g<num>
3. 字符组
(1) 排除型字符组
[^0-9]表示在当前位置,匹配一个0-9之外的字符。排除型字符组必须匹配一个字符。
(2) 字符组简记法
[\d]相当于[0-9], [\w]相当于[0-9a-zA-Z_], [\s]相当于[ \t\r\n\v\f]。
三种简记法的排除型字符组分别为[\D],[\W],[\S]
(3) 匹配任意字符
.(点号)符号在不指定当行匹配模式的情况下可以匹配除\n(换行符)之外的所有字符。
[\d\D](或者[\w\W],[\s\S])可以匹配任意字符。
4. 量词
(1) 常用量词
{m,n}是通用形式的量词,其他量词(*,?,+)都可以由{m,n}来表达:
常用量词 | {m,n的等价方式} | 作用 |
* | {0,} | 可以不出现,也可以出现多次 |
+ | {1,} | 至少出现一次 |
? | {0,1} | 不出现,或者只出现1次 |
(2) 忽略优先量词
*,+,?都是匹配优先量词,亦即在可匹配也可不匹配的情况下优先匹配。
如果要在可匹配可不匹配的情况下暂时不匹配,则可以在上述量词的后面添加一个?符号,使之变为忽略优先量词。
5. Python中的匹配模式
可以在用search, match, findall方法进行匹配时指定匹配模式,常见的匹配模式如下:
匹配模式修饰符 | 作用 |
i | 不区分大小写 |
x | 注释模式 |
m | 多行模式 |
s | 单行模式,在该匹配模式下,.号可以匹配任意字符 |
u | Unicode模式,在该模式下可以匹配中文 |
a | ASCII模式 |
参考文献:
1. 《正则指引》 余晟