【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')
相关推荐
懂点Tech1 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
comedate2 小时前
SMLib 的 Examples 导读:PyAPI / SM_API / SMLib 三组示例怎么读
python·cad·smlib·examples·sm_api
云和数据.ChenGuang2 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠2 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
yivifu2 小时前
能够使用Python正则表达式函数的文本处理工具——Calibre电子书编辑器
正则表达式
川石课堂软件测试2 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
万化冥合3 小时前
PyBox屏幕键盘如何辅助演示键盘操作?
python·计算机外设
车软学堂3 小时前
从测试转开发,到底要补什么
网络·人工智能·python·功能测试·单片机·车载系统·自动化
天空依然蔚蓝3 小时前
分享一个自动检测网站在线状态的python程序
python·运维开发·1024程序员节
2501_937767163 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql