Python高级-正则表达式
第三章 正则表达式
在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验。
1、正则表达式概述
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。
2、re模块
一个正则表达式(或RE)指定了一集与之匹配的字符串;模块内的函数可以让你检查某个字符串是否跟给定的正则表达式匹配模块定义了几个函数,常量,和一个例外。有些函数是编译后的正则表达式方法的简化版本(少了一些特性)。绝大部分重要的应用,总是会先将正则表达式编译,之后在进行操作
那现在我们先熟悉re模块的一简单的方法
compile方法
re.compile(pattern[,flags])
# 作用:把正则表达式语法转化成正则表达式对象
pattern:正则表达式语法
flags定义匹配模式包括:{
re.I:忽略大小写
re.L:表示特殊字符集 \w,\W,\b,\B,\s,\S 依赖于当前环境
re.M:多行模式
re.S:' . '并且包括换行符在内的任意字符(注意:' . '匹配任意字符但不包 括换行符)
re.U:表示特殊字符集 \w,\d,\D,\S 依赖于 Unicode 字符属性数据库
}
search方法
re.search(pattern, string[, flags=0])
# 作用:扫描整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回None。
pattern : 正则表达式对象
string : 要被查找替换的原始字符串。
flags定义匹配模式包括:{
re.I:忽略大小写
re.L:表示特殊字符集 \w,\W,\b,\B,\s,\S 依赖于当前环境
re.M:多行模式
re.S:' . '并且包括换行符在内的任意字符(注意:' . '匹配任意字符但不包括换行符)
re.U:表示特殊字符集 \w,\d,\D,\S 依赖于 Unicode 字符属性数据库
}
match方法
re.match(pattern, string[, flags=0])
# 作用:从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
pattern : 正则表达式对象
string : 需要匹配的字符串
flags定义匹配模式包括:{
re.I:忽略大小写
re.L:表示特殊字符集 \w,\W,\b,\B,\s,\S 依赖于当前环境
re.M:多行模式
re.S:' . '并且包括换行符在内的任意字符(注意:' . '匹配任意字符但不包括换行符)
re.U:表示特殊字符集 \w,\d,\D,\S 依赖于 Unicode 字符属性数据库
}
这里我们分别简单了解一下这些模块,
1、compile方法是将正则表达式转换成对象,
2、search和match方法是根据compile对象转换生成好的规则,进行匹配。
那我们将上方的思考题拿下来,先看思考一下
# 导入模块
>>> import re
# 如何判断一个字符串是手机号呢
tel_1 = '''aesdf13811011234
aa1a3hi233rhi3
87156340
affa124564531346546
afa19454132135'''
# 这里我们不说的过于复杂了,也不说特殊号码了,简单了解一下规则
# 1、由11位正整数字组成
# 2、第一位数字必须由1开头,第二位数字由3-9组成
# 根据这些条件这里即可以生成一个匹配式 1[3,9]\d{9},下面我们会讲解上匹配语法与规则
pattern = re.compile(r'1[3,9]\d{9}')
# 使用search方法,匹配到一个电话号码
print(re.search(pattern, tel_1))
#<re.Match object; span=(7, 18), match='13811011234'>
# 再使用match方法,输出了None
print(re.match(pattern, tel_1))
None
# -----------------------------------------------
# 那我们换一个例子再看,
tel_2 = '''19454132135abuw'''
# 再将匹配表达式转换成匹配对象
pattern = re.compile(r'1[3,9]\d{9}')
# 先使用search方法
print(re.search(pattern, tel_2))
#<re.Match object; span=(0, 11), match='19454132135'>
# 再使用match方法,看到对象响应的结果,出现了需要匹配的号码
print(re.match(pattern, tel_2))
#<re.Match object; span=(0, 11), match='19454132135'>
我们可以发现,更多的时候,我们在字符串或者是一堆单词内容里面不确定范围搜索,可以使用search来进行匹配第一个最先匹配到的正常的电话号码,而match用来匹配第一个注意是第一个字符的,这里的第一个是在被搜索的这串字符的第一位索引上的
这里面我们根据返回回来的内容,看到有三部分
1、re.Match object 对象
2、span=()搜索结果在文本索引位置
3、match匹配结果
这里我们现在就需要急切了解到两个问题
第一、得到的匹配对象re.Match object该如何处理,以及re模块是否存在一些其他的方法
第二、正则表达式的写法
3、Match对象
我们来看一下,Match对象,Match对象是一次匹配的结果,包含匹配的很多信息
Match匹配对象的属性
>>> import re
>>> tel_1 = '''
aesdf13811011234
aa1a3hi233rhi3
87156340
affa124564531346546
afa19454132135'''
>>> pattern = re.compile(r'1[3,9]\d{9}')
>>> results = re.search(pattern, tel_1)
# pos表示搜索的开始的位置,endpos搜索结束的位置
>>> print(results.pos, results.endpos)
0 83
# group表示匹配的结果
>>> print(results.group())
13811011234
>>> tel_2 = '''19454132135abuw'''
>>> results = re.search(pattern, tel_2)
# pos表示搜索的开始的位置,endpos搜索结束的位置
>>> print(results.pos, results.endpos)
0 15
# group表示匹配的结果
>>> print(results.group())
19454132135>>> results = re.search(pattern, tel_2)
# pos表示搜索的开始的位置,endpos搜索结束的位置
>>> print(results.pos, results.endpos)
0 15
# group表示匹配的结果
>>> print(results.group())
19454132135
4、正则表达式
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配元字符 (参见 python 模块 [re 文档](re — 正则表达式操作 — Python 3.12.4 文档))
字符 | 功能 |
---|---|
. | 匹配任意字符(不包括换行符) |
A | 匹配开始位置,多行模式下匹配每一行的开始,(也有取反的意思,区分应用场景) |
$ | 匹配结束位置,多行模式下匹配每一行的结束 |
* | 匹配前一个元字符0到多次 |
十 | 匹配前一个元字符1到多次 |
? | 匹配前一个元字符0到1次 |
{m,n} | 匹配前一个元字符m到n |
\ | 转义字符,跟在其后的字符将失去作为特殊元字符的含义, 例如.只能匹配.,不能再匹配任意字符 |
[] | 字符集, 一个字符的集合,可匹配其中任意一个字符 |
| | 逻辑表达式或,比如a |
(…) | 分组,默认为捕获,即被分组的内容可以被单独取出, 默认每个分组有个索引,从1开始,按照"("的顺序决定索引值 |
(?iLmsux) | 分组中可以设置模式,iLmsux之中的每个字符代表一个模式 |
(?:…) | 分组的不捕获模式,计算索引时会跳过这个分组 |
(?P…) | 分组的命名模式,取此分组中的内容时可以使用索引也可以使用name |
(?P=name) | 分组的引用模式,可在同一个正则表达式用引用前面命名过的正则 |
(?#…) | 注释,不影响正则表达式其它部分 |
(?=…) | 顺序肯定环视,表示所在位置右侧能够匹配括号内正则 |
(?!..) | 顺序否定环视,表示所在位置右侧不能匹配括号内正则 |
(?<=…) | 逆序肯定环视,表示所在位置左侧能够匹配括号内正则 |
(?<!..) | 逆序否定环视,表示所在位置左侧不能匹配括号内正则 |
(?(id/name)yes|no) | 若前面指定id或name的分区匹配成功则执行yes处的正则,否则执行no处的正则 |
\number | 匹配和前面索引为number的分组捕获到的内容一样的字符串 |
VA | 匹配字符串开始位置,忽略多行模式 |
\Z | 匹配字符串结束位置,忽略多行模式 |
\b | 匹配位于单词开始或结束位置的空字符串 |
\B | 匹配不位于单词开始或结束位置的空字符串 |
\d | 匹配一个数字,相当于[0-9] |
\D | 匹配非数字,相当于[^0-9] |
\s | 匹配任意空白字符,相当于[\t\n\r\fv] |
\S | 匹配非空白字符,相当于[^\t\n\r\flv] |
\w | 匹配数字、字母、下划线中任意一个字符,相当于[a-zA-Z0-9] |
\W | 匹配非数字、字母、下划线中的任意字符,相当于-[^\w] |
5、表示字符
’ . ’ 用法
# 导入模块
>>> import re
# 测试匹配任意字符(不包括换行符)使用的re中的match方法
>>> print(re.match(".","a").group())
'a'
>>> print(re.match(".","1").group())
'1'
>>> print(re.match(".","_").group())
'_'
>>> print(re.match(".","0").group())
'0'
# 只有匹配到'\n'时候提示None,说明,匹配任意字符(不包括换行符)
>>> print(re.match(".","\n"))
None
’ [ ] ’ 用法
# 导入模块
>>> import re
# 匹配字符集,区间中的集合,可匹配其中任意一个字符,使用的re中的match方法
# 如果hello的首字符小写,那么正则表达式需要小写的h
>>> print(re.match("h","hello Python").group())
'h'
# 如果hello的首字符大写,那么正则表达式需要大写的H
>>> print(re.match("H","Hello Python").group())
'H'
# 大小写h都可以的情况
>>> print(re.match("[hH]","hello Python").group())
'h'
>>> print(re.match("[hH]","Hello Python"