Python 之正则表达式提取数据
实验环境
- Python 版本:Python 3.6.5
正则表达式
概念
正则表达式就是记录文本规则的代码
特点
- 正则表达式的语法很令人头疼,可读性差
- 正则表达式通用行很强,能够适用于很多编程语言
常见语法
字符
语法 | 说明 | 表达式案例 | 完整匹配字符串 |
---|---|---|---|
一般字符 | 匹配自身 | abc | abc |
. | 匹配任意除换行符\n 外的字符(在 DOTALL 模式中也能匹配换行符) |
a.c | abc |
|转义字符,使其后一个字符表示字符本身 | a.c | a.c | |
[…] | 选取字符范围 | a[bcd]e | abe 或 ace 或 ade |
预定义字符集(也可写在字符集 […] 中)
语法 | 说明 | 表达式案例 | 完整匹配字符串 |
---|---|---|---|
\d | 数字:[0-9] | a\dc | a1c |
\D | 非数字:[^0-9] | a\Dc | abc |
\s | 空白字符:[<空格>\t\r\n\f\v] | a\sc | a c |
\S | 非空白字符:[^<空格>\t\r\n\f\v] | a\Sc | abc |
\w | 单词字符:[A-Za-z0-9_] | a\wc | abc |
\W | 非单词字符:[^A-Za-z0-9_] | a\Wc | a c |
数量词(用在字符或(…)之后)
语法 | 说明 | 表达式案例 | 完整匹配字符串 |
---|---|---|---|
* | 匹配前一个字符0次或无限次 | abc* | abccc |
+ | 匹配前一个字符1次或无限次 | abc+ | abccc |
? | 匹配前一个字符0次或1次 | abc? | abc 或 ab |
{m} | 匹配前一个字符m次 | ab{2}c | abbc |
匹配开头和结尾的正则表达式
语法 | 功能 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
其他
语法 | 功能 |
---|---|
[^指定字符] | 表示除了指定字符都匹配 |
Python 之 re 模块
在 Python 中通过正则表达式提取数据使用的模块为 re
基本用法
# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
示例:
# coding=utf-8
import re
result = re.match("hello", "hello.cn")
print(result.group())
运行结果为:
匹配单个字符
示例:
# coding=utf-8
import re
ret = re.match(".", "L")
print(ret.group())
ret = re.match("f.y", "fly")
print(ret.group())
ret = re.match("f", "fly to sky")
print(ret.group())
ret = re.match("[Ff]", "fly to sky")
print(ret.group())
ret = re.match("[Ff]ly to sky", "fly to sky")
print(ret.group())
ret = re.match("[0123456789]fly to sky", "1fly to sky")
print(ret.group())
ret = re.match("[0-9]fly to sky", "1fly to sky")
print(ret.group())
ret = re.match("[0-35-9]fly to sky", "1fly to sky")
print(ret.group())
运行结果:
匹配预定义字符集
示例:
# coding=utf-8
import re
ret = re.match("fly2", "fly2sky")
print(ret.group())
ret = re.match("fly\d", "fly2sky")
print(ret.group())
match_obj = re.match("\D", "f")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("fly\sto\ssky", "fly to sky")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("fly\sto\ssky", "fly\tto\tsky")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("fly\Sto\Ssky", "fly-to-sky")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("\w", "A")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("\W", "&")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
运行结果:
匹配多个字符
示例:
# coding=utf-8
import re
ret = re.match("[A-Z][a-z]*", "A")
print(ret.group())
ret = re.match("[A-Z][a-z]*", "AaaA")
print(ret.group())
ret = re.match("[A-Z][a-z]*", "Aab")
print(ret.group())
match_obj = re.match("f.+y", "fly")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("https?", "http")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
ret = re.match("[a-zA-Z0-9_]{6}", "123_abc456_def")
print(ret.group())
ret = re.match("[a-zA-Z0-9_]{8,20}", "123_abc456_def")
print(ret.group())
import re
ret = re.match("[A-Z][a-z]*","M")
print(ret.group())
ret = re.match("[A-Z][a-z]*","MnnM")
print(ret.group())
ret = re.match("[A-Z][a-z]*","Aabcdef")
print(ret.group())
运行结果:
匹配开头和结尾及其他
示例:
# coding=utf-8
import re
# 匹配以数字开头的数据
match_obj = re.match("^\d.*", "1fly")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
# 匹配以数字结尾的数据
match_obj = re.match(".*\d$", "fly1")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
# 匹配以数字开头和结尾的数据
match_obj = re.match("^\d.*\d$", "1fly1")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
# 除了指定字符以外都匹配
match_obj = re.match("[^abcefg]", "d")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
运行结果:
高级匹配
compile 方法
- 作用:
对正则表达式进行编译构建对象,后续不需要重新构建正则表达式上下文环境,从而提高效率
使用方式:
# 构建表达式对象 pattern = re.compile(r'表达式') # 通过表达式对象对数据进行操作 pattern.findall(string)
贪婪模式和非贪婪模式
- 贪婪模式:
(.*)
尽可能多的匹配
- 非贪婪模式:
(.*?)
一旦匹配到就结束
DOTALL 模式
.
符号匹配所有的字符包括换行符使用方法:
pattern = re.compile(r'表达式', re.DOTALL) 或 pattern = re.compile(r'表达式', re.S) 或 pattern = re.compile(r'表达式', re.RegexFlag.DOTALL) 或 pattern = re.compile(r'表达式', re.RegexFlag.S)
忽略大小写模式
正则匹配时忽略大小写
使用方法:
pattern = re.compile(r'表达式', re.IGNORECASE) 或 pattern = re.compile(r'表达式', re.I) 或 pattern = re.compile(r'表达式', re.RegexFlag.IGNORECASE) 或 pattern = re.compile(r'表达式', re.RegexFlag.I)
原始字符串 r 的用法
- 让字符串内部的转义字符没有任何意义。
四大检索方法
- match 开头匹配,只匹配一次
- search 全局匹配,只匹配一次
- findall 匹配所有符号条件的数据,返回是 结果列表;数据量小使用
- finditer 迭代对象,迭代 Match 对象;数据量大使用
分组与替换方法
- split 分组 通过给定字符串进行对数据进行分组
- sub 替换 通过给定的正则表达式和替换字符进行替换
示例
# coding=utf-8
import re
string = '''
abcd
abcd
abcD
abcD
'''
# 贪婪匹配
pattern = re.compile(r'a(.*)d')
result = pattern.findall(string)
print(result)
# 非贪婪匹配
pattern = re.compile(r'a(.*?)d')
result = pattern.findall(string)
print(result)
# 贪婪匹配 + DOTALL 模式
pattern = re.compile(r'a(.*)d', re.RegexFlag.S)
result = pattern.findall(string)
print(result)
# 非贪婪匹配 + DOTALL 模式
pattern = re.compile(r'a(.*?)d', re.RegexFlag.S)
result = pattern.findall(string)
print(result)
# 贪婪匹配 + 忽略大小写
pattern = re.compile(r'a(.*)d', re.RegexFlag.IGNORECASE)
result = pattern.findall(string)
print(result)
# 贪婪匹配 + DOTALL 模式 + 忽略大小写
pattern = re.compile(r'a(.*)d', re.RegexFlag.IGNORECASE | re.DOTALL)
result = pattern.findall(string)
print(result)
# 原始字符串 r 的用法
string = r"abc\nd"
pattern = re.compile(r'a(.*)d')
result = pattern.findall(string)
print(result)
# match
string = "123abc"
pattern = re.compile('\d+')
result = pattern.match(string)
print(result.group())
# search
string = "aaa123"
pattern = re.compile('\d+')
result = pattern.search(string)
print(result.group())
string = '''
abc
abc
abc
abc
'''
pattern = re.compile(r'a(.*)c')
# findall
result = pattern.findall(string)
print(result)
# finditer
results = pattern.finditer(string)
for result in results:
print(result.group())
# split
string = "ab;c def,gh; i;jk"
pattern = re.compile(r'[; ,]+')
result = pattern.split(string)
print(result)
# sub 交换
string = "key1 value1;key2;key3;key4;key5 value5"
pattern = re.compile(r'(\w+) (\w+)')
result = pattern.sub(r"\2 \1", string)
print(result)
运行结果: