前言
正则表达式 Re ,简洁表示一组很大的字符串的特征,属于一种通用的字符串表达框架。
1、无穷字符串组
‘PY’ ‘PYY’ ‘PYYY’ ‘PYYYY’…
正则表示为:PY+
2、特殊条件、特点字符串组:
PY后字符数量小于10,且不能再出现PY
正则表示为: PY [ ^PY]{0,10}
用简洁的方法表示某些字符串的共同特征。可以用来匹配、查找、替换字符串。
3、正则表达式的编译:将正则表达式语法的字符串转换为正则表达式的特征。才可以进行后续的实用匹配。
‘PY’ ‘PYN’ ‘PYTN’ ’ PYTHN’ ‘PYTHON’
正则表达式为:P(Y|YT|YTH|YTHO)?N
编译: q = re.compile(P(Y|YT|YTH|YTHO)?N)
1、语法
1.1 基本的操作符
操作符 | 说明 | 实例或备注说明 |
. | 表示任何单个字符 | 备注:除换行符\n外其他任意字符 |
\s | 空格和换行符 ’ ‘’\t’ ‘\n’ | 备注: \S大写S表示非空格换行类字符 |
[] | 字符集合,表示对单个字符给出取值范围 | [abc]表示a,b,c中的一个 |
[ ^ ] | 非字符集合,表示不取集合中的字符 | [ ^abc]表示非a,非b,非c中的一个 |
* | 表示 * 号之前的字符可能出现 0 次或 无限次 | abc*表示可能是ab,abc,abcc,abccc等 |
+ | 表示 + 之前的字符出现 1 次或 无限次 | abc+表示abc,abcc,abccc等 |
? | 前 1 个字符出现 0 次或 1 次 | abc?表示ab或abc |
| | 表示该符号两侧表达式中的一个 | ab|cd 表示ab或者cd中的一个 |
{ m } | 扩展前 1 个字符 m 次 | ab{3}c 表示abbbc |
{ m,n} | 扩展前 1 个字符 m 至 n 次 | ab{1,2}c表示abc 和 abbc |
^ | 匹配字符串的 开头 | ^abc表示abc,而且只在字符串 开头 |
$ | 匹配字符串的 结尾 | abc$ 表示abc, 而且只在字符串的结尾匹配 |
() | 分组标记符 | 和数学运算里的意义类似,(abc)表示abc,(ab|cd)表示 ab 或 cd 的一个 |
\d | 数字,等价于[0-9] | 备注:\D 大写D表示 非 数字 |
\w | 单词符,等价于[A-Za-z0-9_] | 备注:\W 大写W表示非字母数字,即其他符号 |
注意: 区分转义符号 \ 和非转义正则式
如:
'\ \ ’ 在正则匹配时表示: ‘\ ’
’ \ "\d \ " ’ 表示正则式:’ “\d” ’
1.2 常用正则取值语句
由26个英文字母中的一个重复或不重复组成的字符串
^ [A-Za-z]+$
由字母和数字组成的字符串
^ [A-Za-z0-9]+$
整数(包含正负)形式的字符串
^ -?\d+$
正整数形式的字符串
^ [0-9]* [1-9] [0-9]*$
中国区域6位邮政编码
[1-9]\d{5}
匹配中文字符:
[\u4e00-\u9fa5]
国内电话号码:区号有3位010或者4位0531,后面可能8位或者7位
\d(4}-\d(8}l\d{3}-\d{8}
1.3 设计自己需要的字符串正则:
4段IP地址:每段取值0~255
\d+.\d+.\d+.\d+
\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
取值区间都不精确。
可以设计精确地取值区间:
0-99 :[1-9]?\d
100-199 :1\d{2}
200-249 :2[0-4]\d
250-255 :25[0-5]
精确地取法:
((([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])
2、使用方法
因为正则表达式涉及多种符号,可能会和代码里的转义字符串冲突,所以一般常用一个字母 r + 字符串表示使用原生字符串形式,不包含转义符的字符串形式。不再用\ 表示 \
r'text'
r' [1-9]?\d'
使用 re 库的时候可以使用函数式:
re.函数(字符串1,字符串2)
end = re.search(r’[1-9]\d{5}’,‘pk 100086’)
或者 面向对象方法
p=re.compile(字符串1)
end = p.search(字符串2)
p = re.compile(r’[1-9]\d{5}’)
end = p.search(‘pk 100086’)
第二种方法更好,方便之后直接在其他函数时使用。
函数:
re.compile(pattern,flags=0)
flags表示匹配类型 下面search函数里有介绍
2.1 re.search()
在一个字符串中搜索匹配某正则表达式的第一个位置,返回match对象,后面很多符合要求的也只返回第一个。
re.search(pattern,string,flags=0)
- pattern : 正则表达式的字符串或原生字符串形式
- string :待匹配的字符串
- flags :正则表达式使用时的控制标记
- re.I 不区分正则表达式的大小写
- re.S 匹配除换行符的所有字符,也即不将换行符作为新的一行。
- re.M 配合^符号,正则式不仅仅是作用在开头,更可以作用在每一行进行匹配
示例:
import re
match = re.search(r'[1-9]\d{5}','pk 290001')
print(match)
print('--------')
print(match.group(0))
# 在下面第3大部分match对象部分说明
》》
<_sre.SRE_Match object; span=(3, 9), match='290001'>
--------
290001
2.2 re.match()
从一个字符串的开始位置其匹配正则表达式,返回match对象。参数和search相同。
re.match(pattern,string,flags=0)
注意当开始位置不符合正则式的时候匹配值为空:
示例:
match = re.match(r'[1-9]\d{5}','290001 pk')
print(match)
print('--------')
print(match.group(0)) #match对象部分会进一步说明
》》
<_sre.SRE_Match object; span=(0, 6), match='290001'>
--------
290001
但是
match = re.match(r’[1-9]\d{5}’,‘pk 290001’)
就匹配不到了,会报错。
就是需要注意match是从起始位置。即使字符串里面有,不是在起始位置也不能用match去匹配,不然会返回空值NoneType。
2.3 re.findall()
搜索字符串,返回列表形式,包含全部匹配到的字符串
re.findall(pattern,string,flags=0)
参数和之前方法的相同。
示例:
lt = re.findall(r'[1-9]\d{5}','pk 290001 ts 370002') #此处使用了 r 忽略转义符
print(lt)
>>
['290001', '370002']
2.4 re.split()
将一个字符串按照正则表达式进行切割,匹配分割的地方去掉,返回切割后的列表。
re.split(pattern,string,maxsplit=0,flags=0)
其他参数相同,maxsplit表示最大分割数,剩余部分作为最后一个元素输出。
示例:
lt = re.split(r'[1-9]\d{5}','pk 290001 ts 370002')
print(lt)
>>
['pk ', ' ts ', '']
给maxsplit参数值:
lt = re.split(r'[1-9]\d{5}','pk 290001 ts 370002',maxsplit=1)
print(lt) #最大分割数为1,分割一次不再往后进行分割了
>>
['pk ', ' ts 370002']
2.5 re.finditer()
搜索字符串,返回一个匹配结果的迭代对象,可以通过for循环遍历输出每个迭代的match对象。
re.finditer(pattern,string,maxsplit=0,flags=0)
示例:
for t in re.finditer(r'[1-9]\d{5}','pk 290001 ts 370002'):
if t:
print(t.group(0))
>>
290001
370002
通过finditer()函数可以取得一个符合每一次正则表达式匹配的迭代集,可以使用for遍历该结果单独输出。
2.6 re.sub()
在一个字符串中替换所有匹配到的表达式子串,并将替换后的字符串和源字符串组合返回新的。
re.sub(pattern,repl,string,count=0,flags=0)
三个参数相同,另外两个:
repl :用来替换匹配字符串的
count : 匹配的最大替换次数
re.sub(r'[1-9]\d{5}',':tihuan','pk 290001 ts 370002','')
》》
‘pk :tihuan ts :tihuan’
3、match对象
match对象是RE库中一次匹配返回的结果,包含了很多匹配反馈的信息。要想获得每一次匹配返回的match对象,要用finditer()函数
match对象的属性和方法
属性:
属性 | 说明 |
.string | 待匹配的文本 |
.re | 匹配时使用的pattern对象,也即正则式 |
.pos | 正则表达式搜索文本开始的位置 |
.endpos | 正则表达式搜索文本结束的位置 |
uu = re.search(r'[1-9]\d{5}','ts 270001 pk370002')
print('待匹配的字符为 :{}'.format(uu.string))
print('匹配使用的正则式为 :{}'.format(uu.re))
print('正则式进行文本搜索的开始位置 :{}'.format(uu.pos))
print('正则式进行文本搜索的结束位置 :{}'.format(uu.endpos))
》》
待匹配的字符为 :ts 270001 pk370002
匹配使用的正则式为 :re.compile('[1-9]\d{5}')
正则式进行文本搜索的开始位置 :0
正则式进行文本搜索的结束位置 :18
方法:
方法 | 说明 |
.group(0) | 获得匹配后的字符串 |
.start() | 匹配字符串在原始字符串的开始位置 |
.end() | 匹配字符串在原始字符串的结束位置 |
.span() | 返回(.star(),.end()) 返回元组类型,两个位置 |
print('***********')
print('获得匹配后的字符串:{}'.format(uu.group(0))) #(默认只输出第一个)
print('匹配字符串在原字符串的开始位置:{}'.format(uu.start()))
print('匹配字符串在原字符串的结束位置:{}'.format(uu.end()))
print('字符匹配位置元组:{}'.format(uu.span()))
》》
***********
获得匹配后的字符串:270001
匹配字符串在原字符串的开始位置:3
匹配字符串在原字符串的结束位置:9
字符匹配位置元组:(3, 9)
4、RE 库的贪婪匹配和最小匹配
贪婪:就是可以同时匹配不同长度不同字符的字符串,默认匹配最长的。
tt = re.match(r'PY.*N','PYANBNCNDNN')
print(tt.group(0))
>> #默认输出贪婪,最长的那个匹配结果
'PYANBNCNDNN'
最小匹配:是匹配结果最短的。
常见最小匹配操作符:就是加 ?号
操作符 | 说明 |
*? | 前一个字符 0 次或 无限次 扩展 |
+? | 前一个字符 1 次 或无限次扩展 |
?? | 前一个字符 0 次或 1 次扩展 |
{m,n}? | 扩展前一个字符 m-n 次 |