正则表达式(RE)
一. 动机
- 文本处理已经成为计算机的常见工作
- 对文本内容的搜索,定位,提取逻辑比较复杂
- 为了快速方便的解决上述问题,产生了正则表达式
二. 简介
- 定义:即文本的高级匹配模式,提供搜索,替换,查找等功能。其本质是一系列由字符和特殊符号构成的字串,这个字串即正则表达式。
- 匹配原理:通过普通字符和有特定含义的字符来组成字符串,用以描述一定的字符串规则,比如重复,位置等,来表达一类特定的字符串内容。
三. 元字符的使用
-
普通字符
匹配规则: 每个普通字符匹配对应的字符
In [14]: re.findall(‘ab’,‘abcdeabcda’)
Out[14]: [‘ab’, ‘ab’]注意:
- 正则表达式永远是作为一个规则整体匹配
- python中正则表达式可以匹配中文
-
或
元字符 : |
匹配规则: 匹配 | 两侧任意一个正则规则即可In [16]: re.findall(‘ab|cd’,‘abcdefghabcd’)
Out[16]: [‘ab’, ‘cd’, ‘ab’, ‘cd’] -
匹配开始位置
元字符 : ^
匹配规则: 使用^匹配目标字符串开头位置In [18]: re.findall(’^Hello’,‘Hello world’)
Out[18]: [‘Hello’] -
匹配结尾位置
元字符 : $
匹配规则: 使用 $ 匹配目标字符串结尾位置In [20]: re.findall(‘Jame$’,‘Hi,Jame’)
Out[20]: [‘Jame’]注意:正则表达式中如果有^ $ 必然出现在正则表达式的开始和最后。如果同时有^ $则正则必须匹配目标字符串全部内容。
-
匹配任意字符
元字符: .
匹配规则:匹配除换行外的任意一个字符In [25]: re.findall(‘小.’,‘小红说小王欺负小李’)
Out[25]: [‘小红’, ‘小王’, ‘小李’] -
匹配字符集中字符
元字符:[字符集]
匹配规则:匹配字符集中任意一个字符
表达形式:[#abc好坏] --> 匹配[]内任意一个字符
[0-9][a-z][A-Z] --> 匹配区间内的任意一个字符
[-_#0-9a-z] -->混合书写,区间写在后面In [30]: re.findall(’[aeiou]’,‘Hello world’)
Out[30]: [‘e’, ‘o’, ‘o’] -
匹配字符集反集
元字符: [^…]
匹配规则:匹配除了字符集中的任意一个字符In [36]: re.findall(’^[^a-z0-9]…’,‘How are you,Jame’)
Out[36]: [‘How’] -
匹配重复
元字符: *
匹配规则 : 匹配前面的字符出现0次或多次In [38]: re.findall(‘ab*’,‘abcdabbbbadfgg’)
Out[38]: [‘ab’, ‘abbbb’, ‘a’]注意: ab* 当表达b出现0次时是 a 而不是 ab
-
匹配重复
元字符: +
匹配规则: 匹配前面的字符出现1次或多次In [41]: re.findall(‘ab+’,‘abcdabbbbadfgg’)
Out[41]: [‘ab’, ‘abbbb’] -
匹配重复
元字符: ?
匹配规则: 匹配前面的字符出现0次或1次In [48]: re.findall(‘ab?’,‘abcdabbbba’)
Out[48]: [‘ab’, ‘ab’, ‘a’] -
匹配重复
元字符:{n}
匹配规则: 匹配前面的字符出现n次In [52]: re.findall(’[0-9]{11}’,‘15100317765’)
Out[52]: [‘15100317765’] -
匹配重复
元字符: {m,n}
匹配规则:匹配前面的字符出现 m – n 次In [60]: re.findall(’[_0-9a-zA-Z]{6,8}’,‘zhang123’)
Out[60]: [‘zhang123’] -
匹配任意(非)数字字符
元字符: \d \D
匹配规则: \d 匹配任意数字字符 [0-9]
\D 匹配非数字字符 [^0-9]In [61]: re.findall(‘1\d{10}’,‘15910694728’)
Out[61]: [‘15910694728’] -
匹配任意(非)普通字符
元字符 : \w \W
匹配规则: \w 匹配任意普通字符
\W 匹配任意非普通字符说明:普通字符指数字字母下划线(汉字也是普通字符)
In [66]: re.findall(’\w+’,‘Port 27017 App#mongodb’)
Out[66]: [‘Port’, ‘27017’, ‘App’, ‘mongodb’] -
匹配(非)空字符
元字符:\s \S
匹配规则: \s 匹配任意空字符
\S 匹配任意非空字符
说明: 空字符指 空格 \r \n \t \v \fIn [69]: re.findall(’\w+\s+\w+’,‘hello world’)
Out[69]: [‘hello world’] -
匹配开头结尾位置
元字符: \A \Z
匹配规则: \A 匹配字符串开头位置 ^
\Z 匹配字符串结尾位置 $ -
匹配(非)单词边界
元字符: \b \B
匹配规则: \b 匹配单词边界位置
\B 匹配非单词边界位置
说明:数字字母下划线(汉字)和其他字符的交界为单词边界In [73]: re.findall(r’\Bis\b’,‘This is a test’)
Out[73]: [‘is’]
总结:
匹配单个字符: . […] [^…] \d \D \w \W \s \S
匹配重复: * + ? {n} {m,n}
匹配位置: ^ $ \A \Z \b \B
其他 : | () \
四. 正则表达式转义
-
特殊字符: . * + ? ^ $ [] () {} | \
-
当正则表达式需要匹配特殊字符的时候,需要加转义
In [84]: re.findall(’$\d+’,‘月薪$8000’)
Out[84]: [’$8000’] -
raw 字符串
字符串 正则 目标
“\$\d+” --> $\d+ —> “$8000”
r’$\d+’ --> $\d+ —> “$8000”raw字符串不会经过字符串本身转义解析,当正则中包含特殊符号时经常使用这种字符串,省去转义麻烦
五. 贪婪 和 非贪婪
贪婪模式:正则表达式的重复匹配总是尽可能向后匹配更多的内容,比如:* + ? {m,n}
非贪婪:满足重复条件即可,不向后匹配更多内容
贪婪 --》 非贪婪: *? +? ?? {m,n}?
In [115]: re.findall(r’a.+?b’,‘allowb abb acdeb’)
Out[115]: [‘allowb’, ‘abb’, ‘acdeb’]
六. 正则表达式分组
定义: 使用()可以为正则表达式建立内部分组,子组是正则表达式的一个内部整体。
作用:
-
可以被作为内部整体操作,改变元字符的操作对象
In [123]: re.search(r'(张|李)\w+','张三').group() Out[123]: '张三'
-
匹配到内容时子组对应部分可以单独提取
re.search(r'(\w+)://\S+','http://www.baidu.com').group(1)
Out[126]: ‘http’
捕获组(有名字的子组)
命名格式:(?Ppattern)
re.search(r'(?P<pig>ab)cdef','abcdef').group() Out[129]: 'abcdef'
作用: 表达一定的含义,也可以通过名称获取捕获组内容
-
子组注意事项:
【1】 一个正则表达式中可以有多个子组
【2】 子组不要重叠或者过多嵌套
【3】 子组不会影响正则整体匹配的原则
【4】 子组从外到内,从左到右计数
-
六. 正则表达式匹配原则
1. 正确性,能够正确的匹配处目标字符串内容
2. 排他性,除了目标内容,尽可能不会匹配到其他内容
3. 全面性,尽可能做到对目标字符串考虑全面,不遗漏
七. python re模块
regex = compile(pattern,flags = 0)
功能:生成正则表达式对象
参数:pattern 正则表达式
flags 功能标识位,扩展正则表达式功能
返回值: 正则表达式对象
re.findall(pattern,string,flags = 0)
功能: 使用正则匹配目标字符串
参数:pattern 正则
string 目标字符串
返回值: 匹配内容列表,如果正则表达式有子组则只得到子组对应内容
regex.findall(string,pos,endpos)
功能: 使用正则匹配目标字符串
参数:string 目标字符串
pos 设置匹配目标字符串开始位置
endpos 设置匹配目标字符串结束位置
返回值: 匹配内容列表,如果正则表达式有子组则只得到子组对应内容
re.split(pattern,string,flags=0)
功能: 使用正则表达式匹配内容切割字符串
参数:pattern正则
string 目标字符串
返回值: 切割后的内容列表
re.sub(pattern,replace,string,max,flags)
功能: 使用指定字符串替换正则匹配到的内容
参数:pattern 正则
replace 指定字符串
string 目标字符串
max 最多匹配几处
返回值: 替换后的字符串
subn() 用法参数同sub 返回值多一个替换个数
re.finditer(pattern,string,flags)
功能: 使用正则表达式匹配目标内容
参数:pattern 正则
string 目标字符串
返回值: 匹配结果的迭代对象
re.fullmatch(pattern,string,flags)
功能:使用正则表达式完全匹配目标字符串
参数:pattern 正则
string 目标字符串
返回值: 匹配结果的match对象
re.match(pattern,string,flags)
功能:使用正则表达式匹配目标字符串开头
参数:pattern 正则
string 目标字符串
返回值: 匹配结果的match对象
re.search(pattern,string,flags)
功能:使用正则表达式匹配目标字符串第一处匹配内容
参数:pattern 正则
string 目标字符串
返回值: 匹配结果的match对象
regex对象属性变量
flags : 标识位值
pattern : 正则表达式
groups : 子组数量
groupindex : 捕获组名和组序号组成的字典
match对象的属性和方法
-
属性变量
pos 目标字符串开始位置
endpos 目标字符串结束位置
re 正则表达式
string 目标字符串
lastgroup 最后一组组名
lastindex 最后一组序号 -
属性方法
span() 获取匹配内容的起止位置
start() 获取匹配内容的开始位置
end() 获取匹配内容的终止位置
groups() 获取每个子组对应的内容
groupdict() 获取捕获组字典 组名为键,对应内容为值group(n = 0)
功能:获取match对象对应的内容
参数: 数字表示获取相应的子组匹配内容,默认表示全部匹 配内容
子组名称表示获取对应捕获组匹配内容
返回值:匹配的字符串
作业: 1. 熟练掌握正则表达式元字符
2. 将re模块调用函数使用regex对象操作练习
3. 找一个文档完成如下两个正则练习
* 匹配处文档中所有大写字母开头单词
* 匹配出所有数字,包含整数,小数,分数,百分数,负数 123 1.23 1/2 45% -1 -1.7
* 将所有日期格式 2018.7.12 改为2018-7-12
复习:
- 什么是正则表达式
- 元字符
- 正则表达式的转义,贪婪,分组
- 正则表达式匹配原则
- re模块使用
re模块调用
regex对象调用
match对象调用
flags 参数扩展
-
使用函数:re模块直接调用的函数
如:re.compile re.findall re.search… -
作用: 扩展丰富正则表达式匹配功能
-
常用标识位
A == ASCII 元字符只能匹配ascii字符
I == IGNORECASE 匹配时忽略字母的大小写
S == DOTALL 使 . 可以匹配换行
M == MULTILINE 使 ^ $ 可以匹配每一行的开头结尾位置
X == VERBOSE 为正则添加每行注释 -
使用多个flag
方法:使用按位或操作
e.g.: flags = re.I | re.M