正则表达式和re模块
了解正则表达式
正则表达式是对字符串操作的一种逻辑公式,用事先定义好的一些特殊字符,及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符的一种过滤逻辑。正则表达式是用来匹配字符串的强大工具,python中的re模块封装了正则表达式的功能。
一般字符
.(点)匹配除换行符“\n”以外的任意字符
\转义字符,改变特殊意义的元字符,使其变成普通字符
[……]匹配字符组中的字符
[^……]匹配除了字符组中字符的所有字符
\d 等价于匹配[0-9]匹配0-9的数字
\D等价于匹配[^0-9]匹配非0-9的数字
\w等价于[A-Za-z0-9]匹配数字字母
\W等价于[^A-Za-z0-9]匹配非数字字母下划线
\s匹配任意的空白符
\S匹配任意的非空白符
\n匹配一个换行符
\t匹配一个制表符
\b 匹配一个单词的结尾
a|b匹配字符串a或者b
()匹配括号内的表达式,也表示一个组
量词
?等价于匹配长度{0,1}零个或者一个
*等价于匹配长度{0,}零个或者多个
+等价于匹配长度{1,}一个或者多个
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
边界匹配
^匹配字符串的开始,在多行模式中匹配每一行的开头
$匹配字符串的结尾,在多行模式中匹配每一行的结尾
\A仅匹配字符串的开始如:\Aabc
\Z仅匹配字符串的末尾如:abc\Z
逻辑、分组
a|b匹配字符串a或者b,顺序从左到右,一旦匹配就逃过右边的表达式。
(……)括起来的表达式将作为分组,可以后接量词。表达式中的|仅在该组中生效。
(?P<name>)分组,除了原有的编号外再指定一个额外的别名。
\<number>引用编号为<number>的分组匹配的字符串。
(?P=name)引用别名为<name>的分组匹配到的字符串。
贪婪与非贪婪
贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配(python中的数量词默认是贪婪的),而非贪婪模式在整个表达式匹配成功的前提下,尽可能少得匹配。
*?,+?,??,{m,n}?, {m,}? 转为非贪婪模式(尽可能少得匹配)
转义符号\
在python中,使用原生字符串r可以解决所有的转义符号歧义或者漏写,比如r"\d"r"\w"等
正则表达式的示例应用
python中自带了re模块,它提供了对正则表达式的支持。
import re ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里 print(ret) #结果 : ['a', 'a'] ret = re.search('a', 'eva egon yuan').group() print(ret) #结果 : 'a' # 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 ret = re.match('a', 'abc').group() # 同search,不过仅在字符串开始处进行匹配,失败则返回None print(ret) #结果 : 'a' #指定格式切分,返回列表 print(re.split('\d+','one1two2three3four4'))#不保留匹配的项 #结果为:['one', 'two', 'three', 'four', '']
print(re.split('\d+','one1two2three3four4')#加上括号后保留了匹配的项
['one', '1', 'two', '2', 'three', '3', 'four', '4', '']
#替换匹配到的字符串并返回替换后的结果 ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个 print(ret) #evaHegon4yuan4 ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次) print(ret) #finditer 返回一个存放匹配结果的迭代器 ret = re.finditer("\d",'ds3sy4784a') print(ret)#<callable_iterator object at 0x02A013B0> print(next(ret).group())#3 print(next(ret).group())#4
findall的优先级
ret = re.findall("www.(baidu|oldboy).com","www.oldboy.com") print(ret)#['oldboy'] 优先将括号内的内容返回 ret = re.findall("www.(?:baidu|oldboy).com","www.oldboy.com") print(ret)#['www.oldboy.com']?号取消优先
练习
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>") #可以在分组中利用?<name>的形式给分组起名字, #获取的结果可以直接用group(“名字”拿到对应的值) print(ret.group("tag_name"))#h1 print(ret.group())#<h1>hello</h1> ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>") #如果不给分组起名,也可以用\序号来找到对应的组,表示要找的内容和前面组的内容一致 #获取的匹配结果可以直接用group(序号)拿到对应的值 print(ret.group(1))#h1 print(ret.group())#<h1>hello</h1>
print(re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")) #['1', '2', '60', '40', '35', '5', '4', '3'] print(re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")) #只显示括号里面的内容,即使|前面的表达式匹配到了也不会显示,会出现一个空的字符串 #['1', '-2', '60', '', '5', '-4', '3'] ret.remove("") print(ret) #['1', '-2', '60', '5', '-4', '3']#利用remove去除空的字符串
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步