【Re】python正则表达式

前言

正则表达式 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 次

参考嵩天老师课程:http://www.icourse163.org/course/BIT-1001870001

猜你喜欢

转载自blog.csdn.net/dzg_chat/article/details/84190043