一 正则表达式简介

1 概述

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

2 正则表达式分类

1 基本正则表达式 (BRE) 基本正则表达式,grep,sed,vi等软件支持,vim 有扩展 2 扩展正则表达式(ERE) 扩展正则表达式,egrep (grep -E) sed -r 等 3 PCRE 几乎所有高级语言都是PCRE的方言或者变种,python从1.6开始使用SRE正则表达式引擎,可以认为是PCRE子集,见模块re re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。 re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。*

3 正则表达式中常用的字符:

模式 描述
[abc] 字符集合,只能表示一个字符的位置,匹配所包含的任意一个字符
[^abc] 字符集合,只能表示一个字符位置,匹配除去集合内字符的任意一个字符
[a-z] 字符范围,也是一个集合,表示一个字符位置,匹配所包含的任意一个字符
^ 匹配字符串的起始
$ 匹配字符串的结尾
. 匹配任意字符串,除了换行符。
* 匹配任意个字符
? 匹配0个或1个字符
+ 匹配一个或多个字符
[...] 用来表示一组字符,单独列出:[amk],匹配'a'或'm'或'k'
[^...] 用来匹配不在列表中的元素[^abc],匹配不存在a,b,c的情况
re* 匹配0个或多个表达式
re+ 匹配1个或多个表达式
re? 匹配0个或1个有前面的正则表达式定义的片段,非贪婪模式
re{n} 匹配前面n个表达式或字符
re{,n} 匹配前面0-n个
re{n,} 匹配前面n-无穷个
re{m,n} 匹配前面m到n个
ab 匹配a 或 b
\w 匹配字母数字和下划线和汉字
\W 匹配与\w相反
\s 匹配任意空白字符如\t \n \r \f
\S 与\s 相反
\d 匹配任意数字[0-9]
\D 匹配任意非数字 [^0-9]
\A 匹配字符串开始
\Z 匹配字符串结束,如果存在换行,则只匹配到换行前的结束字符串
\G 匹配最后匹配完成的位置
\b 匹配单词边界
\B 不匹配单词边界
(pattern) 使用小括号指定一个子表达式,也叫做分组,捕获后会自动分配组号,从1 开始,可以改变优先级
\数字 匹配对应的分组,(very) \1 匹配的是very very,但捕获的组是group 是very
?:pattern 如果仅仅是为了改变优先级,则不需要捕获分组
(?<name>exp) (?'name' exp) 命名分组
?=exp 零宽度正预测先行断言,断言exp一定在匹配的右边出现,也就是断言后面一定给一个exp 如 f(?=oo)则表示f后面一定有oo,此返回是True或False
?<=exp 零宽度正回顾后发断言,断言exp一定出现在匹配的左边,及就是(?<=f)ood,(?<=t)ook 分别匹配ood前面一定有f,或ook前面一定有t
(?!exp) 零宽度负预测先行断言,断言exp一定不会出现在右侧,也就是说断言的后面一定不是exp
(?<!exp) 零宽度负回顾后发断言,断言exp一定不能出现在左侧,
(? ) 注释
*? 匹配任意次,尽可能少的重复
+? 匹配至少一次, 但尽可能少的重复
{n,}? 匹配至少n次,尽可能少的重复
{n,m}? 匹配至少n次,至多m次,但尽可能少的重复
ignoreCase 匹配时忽略大小写
Singleline 单行模式,". "可以匹配所有字符,包括\n
Multiline 多行模式,^行首 $行尾
IngnorePatternWhitespace 忽略表达式中的空白字符,如果要使用空白字符转义,可使用#来进行注释

4 相关测试

使用工具regester 进行测试,如下

下载地址如下

http://deerchao.net/tools/regester/regester.setup.zh.zip

1 单行和多行匹配相关

单行模式的"."匹配,Windows中的换行是回车换行级\r\n

多行模式中的.号匹配

单行的^匹配

多行的^ 匹配

2 集合匹配相关

[abc]

3 符号相关匹配

\s 匹配空白字符,换行符,制表符和空格 此处匹配到了空格和换行符和tab ,此处的匹配是匹配到一个后,以当前匹配完成的为指针,继续向后匹配

\b 匹配单词起始,对英文有效,中文无效

\d 匹配数字

\w 匹配数字,字母,下划线和汉字

4 次数相关

* 匹配前面的正则表达式0次或多次 匹配0次或多次,0次时匹配到了换行符\r\n + 匹配1次或多次 0有一个,因此被匹配 ? 匹配0次或1次

{n} 匹配n次 默认是贪婪匹配, 其他类似 匹配电话号码

5 分组相关

分组:括号括起来的东西成为分组,有分组就有括号,1 是捕获到的字符,只包含在匹配的字符集合中,0 是全部匹配的总字符

其中1 表示匹配到的字符,其包含在括号中,0表示匹配的总的字符的描述

不显示分组

\数字

分组前面匹配的数字的结果在和后面的指定的分组的组号进行匹配,得到最终的值

分组起名字,默认是对1对应的起名子

6 断言相关

此处f一定出现在oot之前或者k一定出现在ood之前。

此处表示oot一定出现在f之后,或ood一定出现在k之后

此处表示f一定不在ood之前或k一定不在oot之前

此处表示oot前面一定不会出现在k之后或者ood一定不会出现在f。

7 贪婪模式于非贪婪模式 默认是贪婪匹配,则尽可能的匹配更多

此处是非贪婪匹配,一次匹配最少满足条件的情况,则其由于或多次匹配,因此出现两个值

8 忽略大小写匹配

此处未忽略大小写,其直接匹配满足条件的

此处忽略大小写,则匹配的结果包含大写,但其在写入时仍然是按照原本的字符进行写入,而不会对其原有的字符进行改变

重点: 单行模式中,点号"." 可以匹配所有字符,包括换行符,"^"表示整个字符串的开头,"$"表示整个字符串的结尾

多行模式中,"."可以匹配除了换行符外的其他字符,"^"表示行首,"$"表示行尾,开始是指\n后面紧跟的下一个字符,结尾是\n前面的字符。

5 实例 :

1 匹配电话号码

2 匹配URL,合格的URL 必须满足包括//: 以及其URL中不存在括号

3 匹配××× 解析: 针对15位的×××,全数字,针对18位的×××,前17位是数字,最后一位可以是数字和大X和小x 如下

二 正则表达式中常用的函数:

1 re.compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。其能够提高正则表达式的执行效率,如果直接使用re.math每次匹配都需要编译正则,因为计算机不认识人写的正则表达式,因此此处是非常有必要存在的东西

语法格式为: re.compile(pattern[, flags])

参数:
pattern : 一个字符串形式的正则表达式
flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
		1 re.I 忽略大小写
		2 re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
		3 re.M 多行模式
		4 re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
		5 re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
		6 re.X 为了增加可读性,忽略空格和 # 后面的注释

2 re.match函数

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

函数语法:
re.match(pattern, string, flags=0)
函数参数说明:
参数	描述
pattern	匹配的正则表达式
string	要匹配的字符串。
flags	标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法	描述
group(num=0)	匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups()	返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

使用re.compile的匹配,其可用后面加来改变匹配的起始位置,但re.math则不能,其大小写及相关的匹配模式是再re.compile处进行添加的。

邮箱匹配规则:

3 re.search方法

re.search 扫描整个字符串并返回第一个成功的匹配。

函数语法:
re.search(pattern, string, flags=0)
pattern:表示匹配的方法。
string:表示被匹配的字符串。
flags	标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
匹配成功re.search方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法	描述
group(num=0)	匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups()	返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

4 findmatch

5 findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。 注意: match 和 search 是匹配一次 findall 匹配所有。 语法格式为: findall(string[, pos[, endpos]]) 参数: string : 待匹配的字符串。 pos : 可选参数,指定字符串的起始位置,默认为 0。 endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。

6 finditer

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。 re.finditer(pattern, string, flags=0) 参数: 参数 描述 pattern 匹配的正则表达式 string 要匹配的字符串。 flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

6 分组:

1 位置分组匹配

/2 表示其必须与第二个分组的内容一致。 /1 表示其必须与第一个分组的内容一致。

2 关键字分组匹配

其中,可以使用?P<别名>的方式来获取,其返回的结果是一个字典,可以使用字典的key进行提取其values值

#!/usr/bin/poython3.6
#conding:utf-8
import  re
s='''boottle\nbag\nbig\nable'''
regex=re.compile('b(\w+)(?P<mysql>e)')  #找到数字之前一定不是\w的
match=regex.finditer(s)
for  mt  in  match:
    print (mt,1)
    print (mt.groups(),2)  # 返回所有
    print  (mt.group('mysql'),3)
    print (mt.group(0),4)  # 返回匹配对象
    print (mt.group(1),5) # 返回第二个分组
    print  (mt.group(2),6) # 返回第二个分组
    print  (mt.groupdict(),7) #返回一个字典
    print  ('+++++++++++++++++++++++++')

结果如下

三 re 高级用法:

1 sub

Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。

语法:
re.sub(pattern, repl, string, count=0, flags=0) 
参数:
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
批量替换字符串的方法:
总体清0。
#!/usr/bin/poython3.6
#conding:utf-8
import  re
s='''bottle\nbag\nbig\nable'''
regx=re.compile('b\wg')
parment=regx.sub('zhang',s)  #前面写入的是替换的部分,后面写入的是源串
parment1=regx.subn('zhang',s,1)  #此处表示只替换其中的一个,而不是全部,sub默认替换的是全部
print (parment,parment1) # 返回的是替换后的结果

结果如下

#!/usr/bin/poython3.6
#conding:utf-8
import  re
s='os.path([path])'
regx=re.compile('[\.\([\])]')  # 通过匹配提取出path
print (regx.sub('',s)[-len('path'):])  #通过将上述匹配的结果换成空来获取其值,其返回是一个字符串,可通过[-4:]的方式获取到这个path

结果如下

将其整体加上一个数字

2 split

1 参数详解

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下: re.split(pattern, string[, maxsplit=0, flags=0]) 参数: 参数 描述 pattern 匹配的正则表达式 string 要匹配的字符串。 maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。 flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志

2 实例

统计单词出现的次数

#!/usr/local/bin/python3.6
#coding:utf-8
import re
from    collections    import  defaultdict
# 由于其需要匹配特殊字符,而\w属于字母,数字下划线,因此\W 及就可以描述为上述所说的数字但某些字符是paht-aaa的形式,因此
#需要进行保留,因此是[^\w-]
regx=re.compile('[^\w-]+')  #此处的含义是不能包含\w或者-的被匹配
def  charnum(file='.'):
    d = defaultdict(lambda: 0)  # 此处用于构造字典
    with   open(file) as  f:
        for  line  in  f:
            lst=regx.split(line)
            for word  in  lst:
                if   word:  # 此处用于判断是否存在空串,只有不存在的才能进行处理
                    d[word.lower()]+=1  #此处用于进行赋值运算
    return  d
i=0
for x  in  sorted(charnum('/etc/nginx/nginx.conf').items(),key=lambda x:x[1],reverse=True):  #对其进行排序,取1及就是数字进行排序并输出
    if i < 10:
        print  (x)
    i+=1

结果如下

3 python正则表达式的贪婪模式与非贪婪模式

其默认的模式是贪婪模式 使用? 将其改变为非贪婪模式