【Python】从入门到上头— 使用re模块用于快速实现正则表达式需求(11)

正则表达式语法规则

re模块

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它"匹配"了,否则,该字符串就是不合法的。

  • Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,所以要特别注意:
python 复制代码
s = 'ABC\\-001' # Python的字符串
# 对应的正则表达式字符串变成:
# 'ABC\-001'

因此我们强烈建议使用Python的r前缀,就不用考虑转义的问题了:

python 复制代码
s = r'ABC\-001' # Python的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'

先看看如何判断正则表达式是否匹配:

python 复制代码
import  re

a = re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
print(a)
b = re.match(r'^\d{3}\-\d{3,8}$', '010 12345')
print(b)

match()方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None。

使用

python 复制代码
import re

test = '用户输入的字符串'
if re.match(r'正则表达式', test):
    print('ok')
else:
    print('failed')

切分字符串

用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:

python 复制代码
c = 'a b   c'.split(' ')
print(c)
#['a', 'b', '', '', 'c']
  • 无法识别连续的空格

正则切分

python 复制代码
d = re.split(r'\s+', 'a b   c')
print(d)
#['a', 'b', 'c']

无论多少个空格都可以正常分割。加入,试试:

python 复制代码
e = re.split(r'[\s\,]+', 'a,b, c  d')
print(e)
#['a', 'b', 'c', 'd']

再加入;试试:

python 复制代码
f = re.split(r'[\s\,\;]+', 'a,b;; c  d')
print(f)
#['a', 'b', 'c', 'd']

分组

除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)

  • 比如:^(\d{3})-(\d{3,8})$分别定义了2个组,可以直接从匹配的字符串中提取出区号和本地号码
python 复制代码
g = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
print(g.group(0))
print(g.group(1))
print(g.group(2))
#010-12345
#010
#12345

如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来。

  • 注意到group(0)永远是与整个正则表达式相匹配的字符串,group(1)、group(2)......表示第1、2、......个子串。

提取子串非常有用。来看一个更凶残的例子:

python 复制代码
h = '19:05:30'
m =  re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$',h)
print(m.groups())
#('19', '05', '30')

这个正则表达式可以直接识别合法的时间。但是有些时候,用正则表达式也无法做到完全验证,比如识别日期:

python 复制代码
'^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$'

对于'2-30','4-31'这样的非法日期,用正则还是识别不了,或者说写出来非常困难,这时就需要程序配合识别了。

贪婪匹配

当我们在Python中使用正则表达式时,re模块内部会干两件事情:

  • 编译正则表达式,如果正则表达式的语法不合法,会报错;
  • 用编译后的正则表达式去匹配字符串。

如果一个正则表达式要重复使用几千次,出于效率的考虑,我们可以·预编译该正则表达式·,接下来重复使用时就不需要编译这个步骤了,直接匹配:

python 复制代码
# 编译:
re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
# 使用:
a2 = re_telephone.match('010-12345').groups()
print(a2)
# ('010', '12345')
a3 = re_telephone.match('010-8086').groups()
print(a3)
# ('010', '8086')
相关推荐
Kai HVZ29 分钟前
python爬虫----爬取视频实战
爬虫·python·音视频
古希腊掌管学习的神32 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
m0_7482448335 分钟前
StarRocks 排查单副本表
大数据·数据库·python
B站计算机毕业设计超人41 分钟前
计算机毕业设计PySpark+Hadoop中国城市交通分析与预测 Python交通预测 Python交通可视化 客流量预测 交通大数据 机器学习 深度学习
大数据·人工智能·爬虫·python·机器学习·课程设计·数据可视化
路人甲ing..44 分钟前
jupyter切换内核方法配置问题总结
chrome·python·jupyter
C++忠实粉丝1 小时前
Redis 介绍和安装
数据库·redis·缓存
游客5201 小时前
opencv中的常用的100个API
图像处理·人工智能·python·opencv·计算机视觉
wmd131643067121 小时前
将微信配置信息存到数据库并进行调用
数据库·微信
是阿建吖!1 小时前
【Linux】基础IO(磁盘文件)
linux·服务器·数据库
每天都要学信号1 小时前
Python(第一天)
开发语言·python