【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')
相关推荐
阿华的代码王国5 分钟前
MySQL ------- 索引(B树B+树)
数据库·mysql
鸽芷咕24 分钟前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
Hello.Reader33 分钟前
StarRocks实时分析数据库的基础与应用
大数据·数据库
子午35 分钟前
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
人工智能·python·cnn
执键行天涯35 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
风等雨归期43 分钟前
【python】【绘制小程序】动态爱心绘制
开发语言·python·小程序
yanglamei19621 小时前
基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue
前端·数据库·flask
Adolf_19931 小时前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
冯宝宝^1 小时前
基于mongodb+flask(Python)+vue的实验室器材管理系统
vue.js·python·flask
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap