Python中正则表达式的详细教程
1.理解正则表达式
正则表达式是字符串运算的逻辑公式,即“正则字符串”由预先定义的一些特定字符和这些特定字符的组合组成。这个“常规字符串”用于表示字符串的过滤逻辑。
正则表达式是一个非常强大的字符串匹配工具。其他编程语言也有正则表达式的概念,Python也不例外。通过正则表达式,我们可以轻松地从返回的页面内容中提取我们想要的内容。
正则表达式的近似匹配过程如下:1 .依次将表达式与文本中的字符进行比较;2.如果每个字符都能匹配,则匹配成功;一旦存在匹配不成功的字符,匹配就会失败。3.如果表达式中有量词或边界,过程会略有不同。
2.正则表达式的语法规则
下面是Python中正则表达式的一些匹配规则,图片来自CSDN
3.与正则表达式相关的注释(1)量词的贪婪模式和非贪婪模式
正则表达式通常用于在文本中查找匹配的字符串。在Python中,量词默认是贪婪的(或者在少数语言中默认是非贪婪的),总是试图匹配尽可能多的字符;另一方面,不贪婪的人总是试图匹配尽可能少的字符。例如,如果使用正则表达式“ab*”来查找“abbbc”,将会找到“abbb”。如果你用非贪婪的数量词“ab*?”,“一个”就会被发现。
注意:我们一般采用非贪婪模式进行抽取。(2)反斜杠问题
像大多数编程语言一样,正则表达式使用“\”作为转义字符,这可能会导致反斜杠问题。如果需要匹配文本中的字符“\”,那么在用编程语言表示的正则表达式中将需要四个反斜杠“\ \ \”:前两个和后两个用于在编程语言中转义成反斜杠,然后在转换成两个反斜杠后在正则表达式中转义成反斜杠。
Python中的原生字符串很好地解决了这个问题。本例中的正则表达式可以用r“\”表示。同样,匹配数字的“\\d”可以写成r“\ d”。有了原生字符串,妈妈就不用担心会漏掉反斜杠了,写出来的表达式更直观。4.Python Re模块
Python自带re模块,提供对正则表达式的支持。使用的主要方法如下
#返回模式对象重新编译(字符串[,标志]) #以下是函数re。匹配(模式、字符串[、标志])。搜索(模式、字符串[、标志])。split (pattern,string [,maxsplit])re.findall(pattern,string[,flags])re.finditer(pattern,string[,flags])re.sub(pattern,repl,string[,count])re.subn(pattern,repl,String[,count])在介绍这些方法之前,我们先来介绍一下pattern的概念。模式可以理解为匹配模式,那么我们如何得到这种匹配模式呢?很简单,我们需要使用re.compile方法。例如
Pattern=re.compile(r'hello ')我们在参数中传入了本机字符串对象,由编译方法编译生成了一个Pattern对象,然后我们使用这个对象进行进一步的匹配。
此外,您可能已经注意到另一个参数标志。这里,解释一下这个参数的含义:
参数标志是一种匹配模式,其值可以用按位或运算符“|”表示,如re。我| re。M.
可选值有:
?Re。I(ignorrecase):忽略大小写(括号内完整书写,下同)?Re。m(多线):多线模式,改变''和' $ '的行为(见上图)?Re。S (DOTALL):点任意匹配模式来改变“.”的行为?Re。l(拼写:LOCALE):使预定的字符类\w \W \b \B \s \S依赖于当前的语言环境?Re。U (UNICODE):使预定的字符类\ W \ b \ B \ s \ S \ d \ D依赖于UNICODE定义的字符属性?Re。X (VERBOSE):详细模式。在这种模式下,正则表达式可以是多行的,空白字符可以忽略,并且可以添加注释。我们需要在刚才提到的其他几个方法中使用这种模式,比如re.match,我们来逐一介绍一下。
注意:以下七种方法中的标志也意味着匹配模式。如果在模式生成期间已经指示了标志,则没有必要在以下方法中传入该参数。
(1)重新匹配(模式、字符串[、标志])
这个方法将从字符串(我们要匹配的字符串)的开头开始,尝试匹配模式,然后向后匹配。如果遇到不匹配的字符,会立即返回None,如果匹配还没有结束,也会返回None。这两个结果都表明匹配失败,否则,匹配模式成功,匹配终止,字符串没有向后匹配。让我们通过下面的例子来理解
_ _ author _ _=' CQC ' #-*-coding : utf-8-*-# import re module import re #将正则表达式编译成Pattern对象,注意hello前的r表示“原生字符串”pattern=re.compile(r'hello') #使用re.match匹配文本,得到匹配结果。如果无法匹配,它将返回none result1=re。match(模式,“hello”)result 2=re。匹配(模式,' helloocqc!)结果3=re.match(模式,‘你好,CQC!)结果4=re.match(模式,‘你好,CQC!)#如果1匹配成功,如果结果1: #使用match获取分组信息printresult1.group()否则:打印“1”不匹配!#如果2个匹配成功,如果结果2: #使用match获取分组信息printresult2.group()否则:打印' 2个匹配失败!#如果3个匹配成功,ifresult: #使用match获取分组信息printresult3.group()否则:打印' 3个匹配失败!#如果4个匹配成功,如果结果4: #使用match获取分组信息printresult4.group()否则:打印' 4个匹配失败!运行结果
Hellohello3匹配失败!你好匹配分析
1.对于第一个匹配,模式正则表达式是‘hello’,我们匹配的目标字符串也是hello,从头到尾完全匹配,匹配成功。
2.第二个匹配,字符串是helloo CQC,模式匹配可以从字符串头完全匹配,模式匹配结束,同时匹配结束,下面的o CQC不再匹配,返回匹配成功的信息。
3.第三个匹配,string是helo CQC,匹配字符串头中的模式,当找到‘o’时,匹配无法完成,匹配结束并返回None。
4.第四种匹配与第二种匹配原则相同,即使遇到空格字符也不会受到影响。
我们还看到result.group()终于打印出来了。这是什么意思?我们来谈谈Match对象的属性和方法。Match对象是一个匹配的结果,包含了很多关于这个匹配的信息。您可以使用Match提供的可读属性或方法来获取此信息。
属性:1.string:匹配时使用的文本。2.2.re:匹配中使用的模式对象。3.正则表达式在3.pos:文本中开始搜索的索引。该值与具有相同名称的Pattern.match()和Pattern.seach()方法的参数相同。4.结束在文本中搜索的正则表达式的索引。该值与具有相同名称的Pattern.match()和Pattern.seach()方法的参数相同。5.lastindex:是文本中最后捕获的数据包的索引。如果没有捕获到数据包,则为无。6.lastgroup:上次捕获的数据包的别名。如果此数据包没有别名或没有捕获的数据包,它将为无。
方法:1.group([group1,…]):获取一个或多个被组截取的字符串;当指定多个参数时,它们将作为元组返回。Group1可以使用数字或别名;数字0表示整个匹配的子字符串;未填写参数时,返回组(0);不拦截字符串的组返回无;多次截取的组返回最后截取的子串。2.groups([default]):以元组的形式返回所有组截取的字符串。相当于主叫组(1,2,…最后)。Default表示未截取字符串的组被该值替换,默认值为None。3.groupdict([default]):返回字典,其中别名组的别名作为关键字,该组截取的子字符串作为值。不包括没有别名的组。Default和上面的意思一样。4.start([group]):返回字符串中指定组截取的子字符串的开始索引(子字符串第一个字符的索引)。组默认值为0。5.end([group]):返回字符串中指定组截取的子字符串的结束索引(子字符串最后一个字符的索引1)。组默认值为0。6.span([group]):返回(开始(group),结束(group))。7.expand(template):将匹配的数据包替换到模板中并返回。您可以在模板中使用\id或\g或\g引用分组,但不能使用数字0。\id相当于\ g;但是,10将被视为第10组。如果要在\1后表示字符“0”,只能使用\g0。
让我们用一个例子来体验一下
# -*- coding: utf-8 -*-#一个简单的匹配实例import re#匹配以下内容:单词空格单词任意字符m=re.match(r'(\w) (\w)(?P.*)','你好世界!')print 'm.string: ',m.stringprint 'm.re: ',m.reprint 'm.pos: ',m.posprint 'm.endpos: ',m . end posprint ' m . last index print ' m . last group : ',m . last group print ' m . group(): ',m.group()print 'm.group(1,2)3: ',m .# m . re: # m . pos : 0 # m . end pos : 12 # m . last index : 3 # m . last group :符号# m.group(1,2): ('hello ',' world')# m.groups(): ('hello ',' world ','!)# m . group dict(): { ' sign ' : '!} # m . start(2): 6 # m . end(2): 11 # m . span(2):(6,11)# m . expand(r ' \ 2 \ 1 \ 3 '): world hello!(2)重新搜索(模式、字符串[、标志])
Search方法与match方法非常相似,不同的是match()函数只检测字符串开头是否re匹配,search()扫描整个字符串寻找匹配,match()只在0位置匹配成功时返回,在开头位置不匹配成功时返回None。同样,搜索方法的返回对象也匹配()返回对象的方法和属性。让我们用一个例子来感受一下
# import re模块import re #将正则表达式编译成Pattern对象pattern=re.compile(r'world')#使用search()查找匹配的子字符串,并返回None#如果没有匹配的子字符串#在本例中,match=re。搜索(模式,‘你好世界!)如果Match: #使用Match获取分组信息print match . group()# # # output # # world(3)re . split(pattern,string [,maxsplit])
根据可以匹配的子字符串,对字符串进行划分并返回列表。Maxsplit用于指定拆分的最大数量,并不指定所有拆分。让我们通过下面的例子来感受一下。
Import repattern=re。编译(r' \ d ')打印re。拆分(模式,‘一一二二三四’)# # #输出# # #[‘一’、‘二’、‘三’、‘四’、’](4)
搜索字符串,并以列表形式返回所有匹配的子字符串。通过这个例子,我们可以感觉到import re pattern=re。编译(r' \ d ')打印re。查找全部(模式,‘一一二三四’)# # #输出# # #[‘1’、‘2’、‘3’、‘4’](5)re
搜索字符串并返回一个迭代器,该迭代器按顺序访问每个匹配结果(匹配对象)。让我们通过下面的例子来感受一下
导入re模式=re。为re中的m编译(r ' \ d ')。finditer(模式,‘一1二2树344’):打印m . group(),###输出#### 1 2 3 4(6)re(模式,repl,字符串[,计数])
使用取代替换线中每一个匹配的子串后返回替换后的字符串。当取代是一个字符串时,可以使用\id或\ g,\ g引用分组,但不能使用编号0。当取代是一个方法时,这个方法应当只接受一个参数(匹配对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。数数用于指定最多替换次数,不指定时全部替换。
导入re模式=re。编译(r '(\ w)(\ w ')s='我说,你好世界!'打印re.sub(模式,r'\2 \1 ',s)def func(m):返回m . group(1).标题()' ' m.group(2).title()打印re.sub(模式、函数、s) ###输出###说我,世界你好!#我说,你好世界!(7)re.subn(模式、回复、字符串[、计数])
返回(sub(repl,string[,count]),替换次数)。
导入re模式=re。编译(r '(\ w)(\ w ')s='我说,你好世界!'print re.subn(模式,r'\2 \1 ',s)def func(m):返回m . group(1).标题()' ' m.group(2).title()打印re.subn(模式、函数、s) ###输出# # # #("说我,世界你好!",2)#('我说,你好世界!', 2)5.Python Re模块的另一种使用方式
在上面我们介绍了七个工具方法,例如匹配,搜索等等,不过调用方式都是重新匹配,重新搜索的方式,其实还有另外一种调用方式,可以通过模式。匹配,模式。搜索调用,这样调用便不用将模式作为第一个参数传入了,大家想怎样调用皆可。
函数应用程序接口列表
match(string[,pos[,endpos]]) | re.match(pattern,string[,flags])search(string[,pos[,endpos]]) | re.search(pattern,string[,flags])split(string[,maxsplit]) | re.split(pattern,string[,maxsplit])findall(string[,pos[,endpos]]) | re.findall(pattern,string[,string[,flags])| find ITER(string,string[,string[,end[,flags])| re。查找ITER(模式具体的调用方法不必详说了,原理都类似,只是参数的变化不同。小伙伴们尝试一下吧~
小伙伴们加油,即使这一节看得云里雾里的也没关系,接下来我们会通过一些实战例子来帮助大家熟练掌握正则表达式的。
版权声明:Python中正则表达式的详细教程是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。