7、正则表达式
正则表达式
正则表达分类
匹配模式
正则表达式元字符
Python正则表达式
模块方法
对象方法
match
search
fullmatch
findall
finditer
split
sub
subn
escape
compile
正则表达分类
匹配模式
正则表达式元字符
Python正则表达式
模块方法
对象方法
match
search
fullmatch
findall
finditer
split
sub
subn
escape
compile
正则表达式
正则表达式在文本处理领域是及其重要的东西,开发必备技能,1970年代,Unix之父Ken Thompson将正则表达式引入Unix的文本编辑中,由此正则表达式正式普及开来,1980年后,Perl语言对Henry Spencer编写的库重新编写,扩展了很多新的特性,1997年开始,Philip Hazel开发出了PCRE(Perl Compatible Regular Expressions),被PHP和HTTPD等工具采用,这个PCRE也是目前来讲最广泛使用的正则表达式;
正则表达分类
正则表达式也有进行分类,第一种为BRE,即基本正则表达式,Grep、Sed、vi等软件都支持,vim有扩展正则表达式,第二种为ERE,即扩展正则表达式,在原有基础正则表达式之上,又做了一些增强,提供了更多的正则表达式元字符,使我们表达起来更加轻松,如egrep、sed -r等软件都支持;
那么最后一种PCRE,也是目前使用最为广泛的正则表达式,几乎所有高级语言都是PCRE的方言或者变种,它更加的强悍,Python从1.6开始使用SRE正则表达式引擎,可以认为是PCRE的子集,见模块re;
匹配模式
Python有所谓的匹配模式,如单行匹配、多行匹配、忽略大小写等,可以在flags直接指定匹配模式,默认为单行匹配;
匹配模式
|
间写形式
|
说明
|
re.IGNORECASE
|
re.I
|
忽略大小写
|
re.LOCAL
|
re.L
|
使得 \w \W \b \B \s \S 的匹配依赖于当前的语言环境
|
re.MULTITINE
|
re.M
|
多行模式,改变’^’和’$’的行为
|
re.DOTALL
|
re.S
|
使“.”匹配包括换行在内的所有字符
|
re.VERBOSE
|
re.X
|
忽略空白字符和注视
|
re.UNICODE
|
re.U
|
根据Unicode字符集解析字符。这个标志影响 \w、\W、\b、\B
|
re.ASCII
|
re.A
|
对字符串patterns,使\w、\W、\b、\B、\d、\D匹配相应的字符串ASCII码形式,而不是匹配Unicode形式
|
正则表达式元字符
元字符,即,用来描述其他字符的字符,因为我们要做文本匹配,其实就是对字符匹配,那怎么描述想要匹配的字符呢,这个时候就需要用到元字符了,这也就是元字符的作用;
元字符
|
说明
|
^
|
匹配行首
|
$
|
匹配字符串的末尾
|
.
|
匹配除换行符外任意一个字符
|
[abc]
|
字符集合,只能表示一个字符位置,匹配所包含的任意一个字符
|
[^abc]
|
字符集合,只能表示一个字符位置,匹配除集合内字符的任意一个字符
|
[a-z]
|
字符范围,表示一个字符位置,匹配所包含的任意字符,如a、b、c…
|
[^a-z]
|
字符范围,表示一个字符位置,匹配除集合内的所有字符,如1、2、3…
|
\b
|
匹配单词边界,如\bb在文本中找到单词以b开头的单词,类似gerp的\<\>,写在前面就是单词首词匹配,写在后面就是单词尾词匹配
|
\B
|
不匹配单词边界,和上面相反
|
\d
|
匹配一位数字[0-9]
|
\D
|
匹配一位非数字[^0-9]
|
\s
|
匹配一位空白字符,包括换行符、制表符、空格[\f\r\n\t\v]
|
\S
|
匹配一位非空白字符
|
\w
|
匹配[a-zA-Z0-9],包括中文的字
|
\W
|
匹配\w之外的字符
|
*
|
代表重复任意字符任意次,会重复0词或多次
|
+
|
代表重复前面字符任意次,至少1次
|
?
|
代表重复前面字符0次或1次
|
{n}
|
代表重复前面字符n次
|
{n,}
|
代表重复前面字符至少n次
|
{n,m}
|
代表重复前面字符至少n次,至多m次
|
x|y
|
匹配x或y
|
(pattern)
|
使用小括号指定一个子表达式,也叫做分组,分组匹配成功之后,会自动分配组号,从1开始
|
(?P<group_name>:pattern)
|
命名分组
|
\r、\t、\n
|
匹配制表符
|
转义
|
凡是在正则表达式中有特殊意义的字符,如果想使用它的本意可以使用\转义,反斜杠自身使用\\,如果的
|
Python正则表达式
Python使用re模块提供了正则表达式处理的能力,re模块是Python独有的匹配字符串的模块,该模块中提供的很多功能是基于正则表达式实现的,而正则表达式是对字符串进行模糊匹配,提取自己需要的字符串部分,他对所有的语言都通用;
模块方法
re模块提供了很多方法可供使用,其中方法也有相应的功能参数,如下详解;
参数
|
说明
|
pattern
|
正则模式表达式
|
string
|
要进行匹配的字符串
|
flags
|
匹配模式,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
|
compile(pattern,flags=0):编译模式,我们写的表达式叫模式,这个模式不管是简单还是复杂都需要先编译,要做一些词法分析语法分析之类的,编译之后会返回一个regex对象,然后就可以利用这个对象进行模式匹配,在多次使用相同模式匹配时,及其有效,flags为指定当前正则表达式的工作模式,是多行模式,还是单行模式,是否忽略大小写,是否忽略表达式中的空白字符等;
match(pattern,string[, flags]):match从字符串开头(从string字符串的索引0开始)匹配,匹配成功为一个Match对象,匹配使用返回None;
search(pattern,string[, flags]):search从索引为0的位置开始往后找,当成功匹配就立刻停止,不会重复查找,如果匹配不到直接返回None;
fullmatch(pattern,string[, flags]):fullmatch要求全程匹配,即整个字符串需要和正则表达式完全匹配;
findall(pattern, string[, flags]):在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表;
finditer(pattern, string[, flags]):在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回;
split(pattern, string, maxsplit=0[, flags]):split方法用pattern做分隔符切分字符串,分割后返回列表。如果用'(pattern)',那么分隔符也会返回;
sub(pattern, repl, string, count=0[, flags]):sub用于替换字符串中的匹配项;
subn(pattern, repl, string, count=0[, flags]):和sub函数差不多,但返回结果不同,subn返回一个元组(新字符串,替换次数);
purpge():清空正则表达式缓存;
escape(string):在一个字符串中所有非字符串数字字符前面增加反斜杠转移,从Python3.3开始,字符'_'不再被转义;
对象方法
上述方法的返回值大部分都是一个对象,而这个对象也有相应的属性和方法,下面就做一个集合说明;
group:完整形式为group([group1,...]),该方法返回一个或多个捕获组所匹配的内容,如果只有一个参数则返回值是一个单独的字符串,如果有多个参数,返回值为指定分组所匹配到的字符串元组,如果不指定任何参数,group默认为0,如果没有分组匹配,则返回整个匹配到的内容;
groups:完整形式为group(default=None),该方法将返回一个包含所有分组内容的元祖,如果某个没有匹配到内容,则取default所指定的值;
groupdict:完整形式为groupdict(default=None),该方法将返回一个包含所有分组及其所有匹配内容的字典对象,如果某个没有匹配到内容,则取default所指定的值;
start:完整形式为start([group]),该方法将返回指定分组所匹配到的子串切片开始位置,如果该分组没有匹配到内容,则返回-1;
end:完整形式为end([group]),该方法将返回指定分组所匹配到的子串切片结束位置,如果该分组没有匹配到内容,则返回-1;
span:完整形式为span([group]), 该方法的返回值所match.start与match.end这两个方法的返回值所组成的一个元祖(start([group]),end([group]))
re:这个属性返回当前对象的正则表达式对象;
string:这个属性,表示返回metch或search方法的字符串的值;
lastindex:这个属性表示最后一个匹配成功的捕获组索引值,如果没有分组匹配成功则返回None;
lastgroup:这个属性表示最后一个匹配成功的命名组名称,如果没有分组匹配成功,或者最后一个分组不是命名分组,则返回None;
pos:开始搜索的位置,默认为0。endpos是搜索的结束位置,如果endpos比pos还小的话,结果肯定是空的;
endpos:结束搜索的位置;
repl:需要替换的值;
match
match从字符串开头(从string字符串的索引0开始)匹配,匹配成功为一个Match对象,匹配使用返回None;
string="caichangen"
# 从索引0开始匹配,成功
print(re.match('c.*',string).group()) # caichangen
# 从索引1开始匹配,失败
print(re.match('a.*',string)) # None
search
search从索引为0的位置开始往后找,当成功匹配就立刻停止,不会重复查找,如果匹配不到直接返回None;
string="caichangen"
# 查找c和后面一个字符,找到即可停止,不往下继续查找
print(re.search('c.?',string).group()) # ca
fullmatch
fullmatch要求全程匹配,即整个字符串需要和正则表达式完全匹配;
string="caichangen"
# 非全字符匹配
print(re.fullmatch('c.?',string)) # None
# 全字符匹配
print(re.fullmatch('c.*',string).group()) # caichangen
findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表,贪婪模式;
string="caichangen"
# 找到所有与表达式匹配的字符串
print(re.findall('c.?',string)) # ['ca', 'ch']
finditer
在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回,贪婪模式;
string="caichangen"
# 找到所有与表达式匹配的字符串,并作为一个迭代器返回
result=re.finditer('c.?',string)
print(next(result).group()) # ca
print(next(result).group()) # ch
split
split方法用pattern做分隔符切分字符串,分割后返回列表。如果用'(pattern)',那么分隔符也会返回;
string="caichangen"
# 使用a作为分隔符切分,并返回一个列表
print(re.split('a',string)) # ['c', 'ich', 'ngen']
sub
sub用于替换字符串中的匹配项;
string="caichangen"
# 替换匹配的字符串
print(re.sub('a','1',string)) # c1ich1ngen
subn
和sub函数差不多,但返回结果不同,subn返回一个元组(新字符串,替换次数);
string="caichangen"
# 替换匹配的字符串,指定替换次数
print(re.subn('a','1',string,1)) # ('c1ichangen', 1)
escape
在一个字符串中所有非字符串数字字符前面增加反斜杠转移,从Python3.3开始,字符'_'不再被转义;
string="cai/chan?g-en"
# 将特殊字符进行转义
print(re.escape(string)) # cai\/chan\?g\-en
compile
编译模式,我们写的表达式叫模式,这个模式不管是简单还是复杂都需要先编译,要做一些词法分析语法分析之类的,编译之后会返回一个regex对象,然后就可以利用这个对象进行模式匹配,在多次使用相同模式匹配时,及其有效;
string1="caichangen"
string2="caifengjun"
# 编译表达式,得到一个表达式句柄
compile=re.compile('a.?|g.?')
# 利用上面的表达式句柄进行匹配
print(compile.findall(string1)) # ['ai', 'an', 'ge']
print(compile.search(string2).group()) # ai