@author: fighter
Python正则表达式知识点整理。
概述:在处理字符串时,经常会遇到查找符合某些复杂规则字符串的需求,正则表达式就是用于描述这些规则的工具。
首先,我们先掌握一下python中正则匹配需要用到的一些特殊字符。
1、行定位符:就是描述字符串的边界。"^“定义了字符串的开始位置,”$“定义了字符串的结束位置。
example: ^mo ,表示以 “mo” 为开头的字符串,可以匹配 “morning” 、“moabcd"等这些字符串,而不能匹配 类似"acdmo” 这样的字符串。
$mo 表示以"mo” 结尾的字符串,例如上述的 “acdmo”.
2、元字符:python预先定义好,用于统一代指某一类字符。
经常用到的包含以下七种:
① "." :匹配除换行符以外的任意字符。
![在这里插入图片描述]()例:可以匹配 "mr\nM\t" 中的 "m"、"r"、"M"、"\t"。
②"\w":匹配一个数字、字母、下划线或汉字。
③"\W":匹配除数字、字母、下划线或汉字以外的字符,与"\w"相反。
④"\s":匹配单个空白符(包括tab键和换行键)。
⑤"\S":除单个空白符以外的所有字符,与"\s"相反。
⑥"\d":匹配数字,例:可以与"ab3d"中的3匹配。
⑦"\b":匹配单词的开始或者结束,单词的边界通常是空格、标点符号和换行。
例:"i like apple not banana","\ba" 与"apple"中的"a"匹配,
“a\b"与"banana"中的"a"匹配。
3、限定符:匹配特定个数的指定字符,包含以下六种
①"?":匹配前面的字符0次或1次。例:"numbe?r" 可以匹配"numbr"和"number"。
②"+":匹配前面字符至少一次。例:"numbe+r" ,
表示"e"至少出现一次,可以匹配"number"、"numbeer"等。
③" * ":代表匹配前面字符0次或多次。
例:"numbe*r",表示"e"可以出现任意次,可以匹配"numbr"、"number" 或"numbeer"等。
④{n}:代表前面字符正好匹配n次。例:"numbe{2}r" 只能匹配"numbeer"。
⑤{n,}:代表前面字符至少匹配n次。例:"numbe{2,}r" 可以匹配"numbeer" 、"numbeeer"等
⑥{n,m}:代表前面字符至少匹配n次,至多匹配m次。
例:"numbe{2,3}r"可以匹配"numbeer"和"numbeeer"这两种形式。
4、字符类:除了元字符预先定义的匹配模式,用户需要根据需求定义某种匹配的范围,需要用"[]"将其包括。
例:我们想要匹配"a"、"d"、"m"、"h"任意一个字符的匹配方式,
可以写成"[admh]",表示匹配"admh"中四个字母的任意一个。
如果我们想要匹配所有小写字母,可以这样写:[a-z]`,所有数字的话:[0-9]
5、排除字符:根据需求,我们想要除了某些特定字符的任意一个字符,就要使用排除字符。方法就是将指定不要的字符用"[]“括起来,然后在最前面加上”^"。
例:[^abcd]:表示匹配除了"a"、"b"、"c"、"d" 以外的任意一个字符。
6、选择字符:提供多种匹配方式的模式,多个匹配方式之间用"|"隔开。
例如,我们想要匹配三个数字或者三个字母,可以这样写:"(\d{3})|([a-z]{3})"。
7、转义字符:"" 将有特殊意义的字符转换为普通字符.例如"."代表任意字符,如果我们想要正常的"."字符,"127.0.0.1",就需要用到转义字符, 可以这样写匹配模式:"[1-9]{3}\.[0-9]\.[0-9]\.[1-9]"
了解完上述的基本内容,我们就正式开始介绍python中的正则匹配方法。
在Python里,提供了re模块,re模块中提供了一些方法用于实现正则表达式的操作。我们在进行正则匹配之前,需要首先导入re模块:import re
re模块里提供了以下三个方法进行正则匹配:
1、match()方法 :表示 从字符串的起始位置进行正则匹配,如果匹配成功,则返回一个对象,否则返回None.
语法格式:re.match(pattern,string,flags)
参数说明:
1、pattern:表示匹配模式
2、string:表示目标字符串,也就是要匹配的字符串。
3、flags:可选参数,用于控制匹配方式,常用的例如:re.I,表示无视字母大小写匹配。
import re
pattern = "[a-z]{3}"
string = "Abcde123acb"
match = re.match(pattern,string,re.I)
print(match)
打印结果:
<_sre.SRE_Match object; span=(0, 3), match='Abc'>
是一个对象!!!
这个对象有几个方法:
1、start():表示开始匹配的位置。
2、end():匹配的结束位置
3、span():返回一个以开始位置和结束位置组成的元组
4、string:表示目标字符串,注意后面没有小括号!!
5、group():表示匹配的结果
print(match.start()) #结果 0
print(match.end()) # 3
print(match.span()) #(0,3)
print(match.string) # Abcde123acb
print(match.group()) #Abc
2、search()方法:与match()方法类似,唯一区别:search用于在整个字符串中搜索第一个符合匹配结果的对象。也就是说,search不仅仅在字符串的起始位置匹配,其他位置有符合的匹配也可以搜索,需要注意的是该方法搜索到第一个匹配成功的对象就不再搜索,直接返回结果。
import re
pattern = "[a-z]{3}"
string = "Abcde123acb"
match = re.search(pattern,string,re.I)
print(match.group())
打印结果:
Abc
3、findall()方法:用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表形式返回。如果匹配成功,则返回包含所有匹配结果的列表,否则返回空列表。注意:该方法与前两个方法的返回结果不一样!!
语法格式:
findall(pattern,string,flags)
上述参数与match方法的一样。
import re
pattern = "[a-z]{3}"
string = "Abcde123acb"
match = re.findall(pattern,string,re.I)
print(match)
打印结果:
['Abc', 'acb']
注意:findall()方法返回一个普通的列表,不存在match和search返回
对象的start、end等五个方法,只需要使用列表操作就行。
拓展:
一、compile()方法
我们都知道,python是解释型语言,每运行一次代码,都需要从上至下的进行解释运行,那么在实际项目中可能需要正则匹配多次,例如用户名、密码等,为了提升性能与代码运行速度,我们引入一个compile 模板。该模板原理是将需要多次匹配的pattern先进行解释,形成一个二进制文件,这样代码每次调用他进行正则匹配的时候就不用再解释一次。话不多说,直接写用法。
语法格式:
compile = re.compile(pattern,flags)
match = compile.match(目标字符串) |search(目标字符串) | findall(目标字符串)
例:
import re
pattern = "[a-z]{3}"
string = "Abcde123acb"
compile = re.compile(pattern,re.I)
match = compile.findall(string)
print(match)
打印结果:
['Abc', 'acb']
总结:通过将正则匹配模式先生成二进制码文件,预先编号模板,
通过模板调用上述三个正则匹配的方法。
二、group()用法
表示分组的意思,对应着正则匹配pattern中的小括号,group()小括号里可以填写数字,表示选择pattern中第几个小括号匹配到的内容。
例:"(\d+)([a-z]+)(\d+)([a-z]+)",这个pattern中含有四个小括号,group(1)表示匹配(\d+)这个里面匹配到的东西。如果小括号里不写东西或者group(0)表示将匹配到的整个字符串打印。
import re
pattern = "(\d+)([a-z]+)(\d+)"
string = "Abcde123acb888acd"
compile = re.compile(pattern,re.I)
match = compile.search(string)
print(match.group()) # 打印结果:123acb888
print(match.group(0)) # 打印结果:123acb888
print(match.group(1)) # 打印结果:123
print(match.group(2)) # 打印结果:abc
print(match.group(3)) # 打印结果:888
注意:group()小括号内是从1 开始的。
Python的re模块中除了上述匹配方法外,还有以下两个比较常用的方法。
1、sub()方法:将目标字符串中符合正则匹配的字符替换成我们想要的字符,最终返回结果是一个新的字符串。
语法:sub(pattern,replace,string,count,flags)
参数说明:
1、pattern:表示匹配模式
2、replace:表示要替换成的字符串
3、string:目标字符串
4、count:可选参数,表示模式匹配后替换的最大次数,默认值为0,表示替换所有匹配。
5、flags:可选参数,用于控制匹配方式,常用的例如:re.I,表示无视字母大小写匹配。
例:
import re
pattern = "\d+"
string = "Abcde123acb888acd"
#将字符串中的数字替换成”成功“两个字
newstr = re.sub(pattern,"成功",string)
print(newstr)
打印结果:
Abcde成功acb成功acd
增加替换次数:
import re
pattern = "\d+"
string = "Abcde123acb888acd"
newstr = re.sub(pattern,"成功",string,1)
print(newstr)
打印结果:
Abcde成功acb888acd
2、spilit()方法:将目标字符串按照正则匹配的字符串进行切割,最终返回结果是一个列表。
语法:re.split(pattern,string,maxSplit,flags)
参数说明:
1、pattern:正则匹配模式。
2、string:目标字符串。
3、maxSplit:可选参数,按照正则匹配字符串切割的最大切割次数,如果不写表示最大切割。
4、flags:可选参数,用于控制匹配方式,常用的例如:re.I,表示无视字母大小写匹配。
例:
import re
pattern = "\d+"
string = "Abcde123acb888acd"
newstr = re.split(pattern,string)
print(newstr)
打印结果:
['Abcde', 'acb', 'acd']
增加切割次数maxSplit
import re
pattern = "\d+"
string = "Abcde123acb888acd"
newstr = re.split(pattern,string,1)
print(newstr)
打印结果:
['Abcde', 'acb888acd']
正则里的贪婪匹配和非贪婪匹配
例:
import re
string ="mnaxca"
pattern="mn.*a"
贪婪匹配:像上例,匹配结果为"mnaxca",也就是最大限度的满足".*" 的任意多个字符。
非贪婪匹配:上例匹配结果是"mna",就是只要符合匹配就停止匹配,
因为".*"代表匹配0个或多个任意字符,那么最简单的就是0个字符咯,也就是匹配到"mna"
两者如何区分?我们看一下下边这个例子:
import re
string ="abcaxc"
pattern="ab.*c"
match = re.match(pattern,string)
print(match.group())
打印结果:
abcaxc
………………………………
import re
string ="abcaxc"
pattern="ab.*?c" #注意:此处的"*"号多了个“?”号
match = re.match(pattern,string)
print(match.group())
打印结果:
abc
总结:贪婪匹配是匹配最大限度的符合正则匹配模式的字符串;
非贪婪匹配是在限定符后面加上一个问号,匹配最小限度的符合正则匹配模式的字符串。