大话 Python:python 基础巩固 -- 灵活运用正则表达式完成数据提取与筛选
在一般的后端语言中都有正则表达式的使用,个人觉得正则表达式的难点就是有比较多的元字符比较难记,所以建议大家收藏。而在 python 的编程中,特别是爬虫之后的数据筛选、清洗等操作都需要对字符串进行大量的操作,使用正则表达式无疑是最简便的一种字符串处理操作。
1、正则表达式的元字符及组装形式
首先,正则表达式就是由一个一个的元字符组合起来的一个字符串,然后以这个字符串作为格式去匹配任意的字符串最后生成新的数据文本。那么,先来看一下在 python 中像这样的元字符到底有哪些。
1. 匹配任意字符(不包括换行符)
2^ 匹配开始位置,多行模式下匹配每一行的开始
3$ 匹配结束位置,多行模式下匹配每一行的结束
4* 匹配前一个元字符0到多次
5+ 匹配前一个元字符1到多次
6? 匹配前一个元字符0到1次
7{m,n} 匹配前一个元字符m到n次
8\\ 转义字符,跟在其后的字符将失去作为特殊元字符的含义,例如\\.只能匹配.,不能再匹配任意字符
9[] 字符集,一个字符的集合,可匹配其中任意一个字符
10| 逻辑表达式 或 ,比如 a|b 代表可匹配 a 或者 b
11(...) 分组,默认为捕获,即被分组的内容可以被单独取出,默认每个分组有个索引,从 1 开始,按照"("的顺序决定索引值
12(?iLmsux) 分组中可以设置模式,iLmsux之中的每个字符代表一个模式,用法参见 模式 I
13(?:...) 分组的不捕获模式,计算索引时会跳过这个分组
14(?P<name>...) 分组的命名模式,取此分组中的内容时可以使用索引也可以使用name
15(?P=name) 分组的引用模式,可在同一个正则表达式用引用前面命名过的正则
16(?#...) 注释,不影响正则表达式其它部分,用法参见 模式 I
17(?=...) 顺序肯定环视,表示所在位置右侧能够匹配括号内正则
18(?!...) 顺序否定环视,表示所在位置右侧不能匹配括号内正则
19(?<=...) 逆序肯定环视,表示所在位置左侧能够匹配括号内正则
20(?<!...) 逆序否定环视,表示所在位置左侧不能匹配括号内正则
21(?(id/name)yes|no) 若前面指定id或name的分区匹配成功则执行yes处的正则,否则执行no处的正则
22\number 匹配和前面索引为number的分组捕获到的内容一样的字符串
23\A 匹配字符串开始位置,忽略多行模式
24\Z 匹配字符串结束位置,忽略多行模式
25\b 匹配位于单词开始或结束位置的空字符串
26\B 匹配不位于单词开始或结束位置的空字符串
27\d 匹配一个数字, 相当于 [0-9]
28\D 匹配非数字,相当于 [^0-9]
29\s 匹配任意空白字符, 相当于 [ \t\n\r\f\v]
30\S 匹配非空白字符,相当于 [^ \t\n\r\f\v]
31\w 匹配数字、字母、下划线中任意一个字符, 相当于 [a-zA-Z0-9_]
32\W 匹配非数字、字母、下划线中的任意字符,相当于 [^a-zA-Z0-9_]
来源说明:以上元字符表说明引用自“博客园,菜鸟的日常”
2、python 的内置模块 re 操作正则表达式的模式
python 的 re 模块提供了很多内置的函数来操作正则表达式,掌握正则表达式以及这些函数的使用会更大的提高工作效率,因为大多时候都是在和字符串打交道。并且 re 模块在使用这些函数来操作正则表达式的时候都可以指定不同类型的模式。比如:re 内置模块的 compile(pattern, flags=0) 函数中的 flags 参数就是用于指定匹配模式的,默认情况下各个内置函数的模式都等于零就是不指定模式。
1re.I 使匹配对大小写不敏感
2re.L 做本地化识别(locale-aware)匹配
3re.M 多行匹配,影响 ^ 和 $
4re.S 使 . 匹配包括换行在内的所有字符
5re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
6re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
3、re 模块函数匹配正则表达式操作字符串
compile(pattern, flags=0) 对匹配的正则表达式进行预编译,这种模式有利于后续对同一种匹配规则的复用,当然也可以不进行预编译使用 re 模块的内置函数直接进行正则表达式的使用。
findall(pattern, string, flags=0) 找到所有的匹配以后的数据,并且使用列表的形式返回匹配后的数据。
1# 导入 re 内置模块
2import re
3# 定义多行字符串 sc
4sc = '''str1
5str2
6str3'''
7
8# 使用 compile() 函数进行正则表达式对预编译
9# 其中正则表达式为<.+>参照元字符表,表达式中<.>表示匹配任意字符(不包括换行符)
10# <+> 表示匹配前一个元字符1到多次,组合<.+>就表示匹配所有字符不包括换行符
11pattern = re.compile(".+")
12# 正则表达对象调用 findall() 函数返回列表
13print pattern.findall(sc)
14# 打印返回列表,结果应该是下面列表
15['str1', 'str2', 'str3']
split(pattern, string, maxsplit=0, flags=0) 按照正则表达式匹配的数据为切割点,对原来的数据进行切分并返回一个数据列表。
1# 定义原始字符串
2sc = '''strw 1 laow
3 strd 2 laow
4 strc 3 laow'''
5# 按照数字切分
6print re.split('\d+', sc)
7# 打印结果
8['strw ', ' laow\n strd ', ' laow\n strc ', ' laow']
sub(pattern, repl, string, count=0, flags=0) 匹配正则表达式的字符串并且替换成指定的字符串后返回。
1# 导入内置模块 re
2import re
3# 定义原始字符串
4sc = "the sum of 6 and 9 is [6+9]."
5# 将[6+9]替换为15
6print re.sub('\[6\+9\]', '15', sc)
7# 打印结果
8the sum of 7 and 9 is 15.
search(pattern, string, flags=0) 查找正则表达式内容。
1# 导入内置模块 re
2import re
3# 定义原始数据
4sc = '''strw 1 laow
5 strd 2 laow
6 strc 3 laow'''
7# 找到第一个以 t 开头的字符串
8sc_res = re.search('t\w+', sc)
9# 必须使用返回对象的 group() 函数才能打印出值,因为 search() 函数返回的是对象
10print sc_res.group()
escape(pattern) 字符串的转义函数,当需要处理的字符串中包含正则表达式中的元字符时必须对原正则表达式进行转义,否则会导致匹配不正确。
1# 导入内置模块 re
2import re
3# 定义原始字符串
4sc = ".+\d222"
5# 将正则表达式<.+\d222>进行转义
6pattern_str = re.escape(".+\d222")
7# 打印转移后的正则表达式
8print pattern_str
9# 打印结果
10\.\+\\d222
11# 打印匹配后的字符串
12print re.findall(pattern_str, sc)
13# 打印结果
14['.+\\d222']
4、总结
除了上述第三点中列举的常见内置函数的使用,还有关于 python 内置的正则表达式的用法还有分组、环视等使用方法。能够帮助我们处理字符串的大多数问题,正则表达式在 python 中的使用非常强大、也是后端语言中使用比较高的,建议大家收藏。
更多精彩前往微信公众号【Python *】,专注后端编程实战,原创文章每天更新!