【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')
相关推荐
w236173460131 分钟前
深入解析布尔注入:原理、实战与防御
数据库·网络安全·sql注入·布尔注入·数据库注入
Elastic 中国社区官方博客4 小时前
如何在不同版本的 Elasticsearch 之间以及集群之间迁移数据
大数据·数据库·elasticsearch·搜索引擎·全文检索·logstash
qq_366086225 小时前
union all几个常见问题及其解决方案
数据库
失去妙妙屋的米奇7 小时前
matplotlib数据展示
开发语言·图像处理·python·计算机视觉·matplotlib
搞不懂语言的程序员7 小时前
备忘录模式深度解析与实战案例
数据库·python·备忘录模式
爱的叹息8 小时前
关于 JDK 中的 jce.jar 的详解,以及与之功能类似的主流加解密工具的详细对比分析
java·python·jar
Lhuu(重开版8 小时前
2025第十六届蓝桥杯PythonB组部分题解
python
程丞Q香8 小时前
python——学生管理系统
开发语言·python·pycharm
手揽回忆怎么睡9 小时前
mongodb学习
数据库·学习·mongodb
dragon_perfect9 小时前
ubuntu22.04上设定Service程序自启动,自动运行Conda环境下的Python脚本(亲测)
开发语言·人工智能·python·conda