TOC

正则表达式

    正则表达式在文本处理领域是及其重要的东西,开发必备技能,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

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注