目录
1 简介
- 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
- 在了解模式之前,需要了解正则表达式的各种元字符的使用。
- 本文例子使用
re.findall()
函数进行演示,该函数用于在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。后续再分享re模块各个函数的详细功能。 - 元字符:可以简单认为一个有特殊含义的符号。
2 限制匹配的字符(集)
2.1 匹配单个字符
- 元字符:
.
- 匹配规则:匹配除换行符外的任意一个字符。
print(re.findall('张.','张三李四'))
#输出['张三']
2.2 匹配字符集中的某个字符
- 元字符:
[字符集]
- 匹配规则:匹配字符集中的任意一个字符。
# [abc#!中文]:表示匹配能匹配到其中任意一个字符即可。
# [0-9]:表示0~9任意一个数
# [a-z]:表示任意一个小写字母
# [A~Z]:表示任意一个大写字母
print(re.findall('[0-9]','abc123'))
#输出['1','2','3']
2.3 匹配字符集中不存在的字符
- 元字符:
[^字符集]
- 匹配规则:匹配除了字符集以外的任意一个字符。
print(re.findall('[^0-9]','abc123'))
#输出['a', 'b', 'c']
print(re.findall('[^ ]+','port-9 Error #404# %@STD'))
#输出['port-9', 'Error', '#404#', '%@STD']
2.4 匹配任意(非)数字字符
- 元字符:
\d
与\D
- 匹配规则:
\d
匹配任意数字字符,等同于[0-9]
;\D
匹配任意非数字字符,等同于[^0-9]
。
print(re.findall('\d{1,5}','Mysql:3306; http:80'))
#输出['3306', '80']
2.5 匹配任意(非)普通字符
- 元字符:
\w
与\W
- 匹配规则:
\w
匹配普通字符;\W
匹配非普通字符。 - 说明:普通字符指数字、字母、下划线、汉字等,utf-8的普通字符都能匹配到,如日语等。
print(re.findall('\w+','server_port = 8888')) #+号含义见下文
#输出['server_port', '8888']
print(re.findall('\W+','server_port = 8888'))
#输出[' = ']
2.6 匹配任意(非)空字符
- 元字符:
\s
与\S
- 匹配规则:
\s
匹配空字符;\S
匹配非空字符。 - 说明:空字符指 空格、\r、\n、\t、\v、\f 等字符。
print(re.findall('\S+','server_port = 8888'))
#输出['server_port', '=', '8888']
print(re.findall('\s+','server_port = 8888'))
#输出[' ', ' ']
3 限制匹配起终点
3.1 匹配字符串开始位置
- 元字符:
^
等同于\A
- 匹配规则:匹配目标字符串的开头位置。
print(re.findall('^Jame','Jame hello'))
#输出['Jame']
print(re.findall('^Jame','hello Jame'))
#输出[],因为Jame不在字符串开头,故匹配不上。
print(re.findall('\AJame','Jame hello'))
#输出['Jame']
print(re.findall('\AJame','hello Jame'))
#输出[],因为Jame不在字符串开头,故匹配不上。
3.2 匹配字符串的结束位置
- 元字符:
$
等同于\Z
- 匹配规则:匹配目标字符串的结尾位置。
- 小技巧:元字符^和$必然出现在正则表达式的开头或结尾处。如果两者同时出现,则中间的部分必须匹配整个目标字符串的全部内容。
print(re.findall('Jame$','Jame hello'))
#输出[],因为Jame不在字符串结尾,故匹配不上。
print(re.findall('Jame$','hello Jame'))
#输出['Jame']
print(re.findall('Jame\Z','Jame hello'))
#输出[],因为Jame不在字符串结尾,故匹配不上。
print(re.findall('Jame\Z','hello Jame'))
#输出['Jame']
print(re.findall('^Jame$','Jame'))
#输出['Jame'],完全匹配
print(re.findall('\AJame\Z','Jame'))
#输出['Jame'],完全匹配
3.3 匹配(非)单词的边界位置
- 元字符:
\b
与\B
- 匹配规则:
\b
表示单词边界,\B
表示非单词边界。 - 匹配规则说明:单词边界指的是数字、字母、汉字、下划线与其他字符的交界位置。
- 例子说明:匹配模式中在字符串签名加了字母r,表示是原生字符串,下节再分析加不加r的区别。
print(re.findall(r'\bis\b','This is a test.'))
#输出['is'],此处输入的是句子中的单词is,而不是This中的is。
print(re.findall(r'\Bis\b','This is a test.'))
#输出['is'],此处输入的是This中的is。
4 限制匹配的数量
当可能存在不同数量匹配情况时,默认规则下为贪婪算法,后续章节再分析贪婪算法与非贪婪算法(或者称为懒惰算法)。
4.1 匹配0次或多次
- 元字符:
*
- 匹配规则:匹配前面的字符出现0次或多次。
print(re.findall('wo*','wooooo~w!'))
#输出['wooooo', 'w']。句末出现了w但是没有o,也是能够匹配上该模式。
print(re.findall('[a-zA-Z]*','How are you?'))
#输出['How', '', 'are', '', 'you', '', ''],出现空字符,是因为*解析为0个字符。
4.2 匹配1次或多次
- 元字符:
+
- 匹配规则:匹配前面的字符出现1次或多次。
print(re.findall('wo+','wooooo~w!'))
#输出['wooooo']。句末的w后面没有o,不能够匹配上该模式。
4.3 匹配0次或1次
- 元字符:
?
- 匹配规则:匹配前面的字符出现0次或1次。
print(re.findall('-?[0-9]+','Jame age 18, and -26'))
#输出['18', '-26']。
print(re.findall('ab?','abbbb,abcda'))
#输出['ab', 'ab', 'a']。
4.4 匹配出现精准次数
- 元字符:
{n}
- 匹配规则:匹配前面的字符出现n次。
print(re.findall('1[0-9]{10}','Jame 18888888888')) #用于匹配手机号码
#输出['18888888888']。
4.5 匹配出现模糊次数
- 元字符:
{n,m}
- 匹配规则:匹配前面的字符出现 n~m 次,包含 n 和 m 。
print(re.findall('[1-9][0-9]{5,10}','Jame 888888')) #用于匹配QQ号码
#输出['888888']。
5 其他元字符
5.1 匹配或关系
- 元字符:
|
。 - 匹配规则:匹配 “|” 两侧任意的正则表达式即可。
print(re.findall('com|cn','www.baidu.com/www.tmooc.cn'))
#输出['com','cn']
5.2 分组匹配
- 元字符:
()
。 - 定义:在正则表达式中,以()建立正则表达式的内部分组,子组是正则表达式的一部分,可作为内部整体操作的对象。
- 该元字符用法较复杂,需多加理解。更多内容参考《【python之re模块学习第4天】正则表达式的应用:分组》
5.3 转义
- 元字符:
\
。 - 匹配规则:如果使用正则表达式匹配特殊字符,则需加 \ 表示转义。
- 特殊字符包括上述各类元字符:
. * + ? $ [] () {} | \
。 - 转义符号与原生字符串的理解将在后续文章中给出。
print(re.findall(r'-?\d+\.?\d*','100, -100, 1.2, 1, -1.2'))
#输出['100', '-100', '1.2', '1', '-1.2']
6 总结
- 熟记每个元字符的作用;
- 虽然每个元字符看起来作用很单一,但是组合起来却是非常复杂,需要在实践中多尝试摸索。
参考文献
- 《Python3 正则表达式》菜鸟教程。
- 《RE正则表达式模块》Python视频教程,推荐观看。