python正则表达式re模块_Python正则表达式 re模块

Python正则表达式re模块

re模块(* * * * *)

就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

正则 就是对字符串进行模糊匹配

字符匹配(普通字符,元字符):

1、普通字符:大多数字符和字母都会和自身匹配

>>> re.findall('alvin','yuanaleSxalexwupeiqi')

['alvin']

2、元字符: .  ^  $  *  +  ?  { }  [ ]  |  ( )  \的详细解释:

^

匹配行首,以 xxx为开头

$

匹配行尾,以xxx结尾。

\

转义字符,如果要匹配\本身,需要使用再次转义:\\。

一些特殊字符:

\d:匹配:[0-9]

\D:匹配:[^0-9]

\s:匹配:任何空白符,即:[\t\n\r\f\v]

\S:匹配:任何非空白符,即:[^\t\n\r\f\v]

\w:匹配:[a-zA-Z0-9_ ]

\W:匹配:[^a-zA-Z0-9_ ]

*

匹配前一个字符或子表达式出现 0次或多次。

+

匹配前一个字符或子表达式出现 1次或多次。

?

(1) 匹配前一个字符或子表达式出现 0次或1次。

(2) 跟在 * 或 + 后面表示非贪婪匹配:

*? 匹配0个

+? 匹配1个

importre#贪婪模式,会尽量多地去匹配

r1 = re.compile(r'ab+')

s1= 'abbb'

print(re.findall(r1,s1)) #['abbb']

#非贪婪模式,会尽量少地去匹配

r2 = re.compile(r'ab+?')

s2= 'abbb'

print(re.findall(r2,s2)) #['ab']

{}

匹配前一个字符或子表达式出现指定次数:

{0,}:0次或多次,相当于 *

{1,}:1次或多次,相当于 +

{0,1}:0次或1次,相当于 ?

{m,n}:m次到n次(m <= n)

importre

ret=re.findall('a..in','helloalvin')print(ret)#['alvin']

ret=re.findall('^a...n','alvinhelloawwwn')print(ret)#['alvin']

ret=re.findall('a...n$','alvinhelloawwwn')print(ret)#['awwwn']

ret=re.findall('a...n$','alvinhelloawwwn')print(ret)#['awwwn']

ret=re.findall('abc*','abcccc')#贪婪匹配[0,+oo]

print(ret)#['abcccc']

ret=re.findall('abc+','abccc')#[1,+oo]

print(ret)#['abccc']

ret=re.findall('abc?','abccc')#[0,1]

print(ret)#['abc']

ret=re.findall('abc{1,4}','abccc')print(ret)#['abccc'] 贪婪匹配

注意:前面的 *,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配(非贪婪匹配)

ret=re.findall('abc*?','abcccccc')print(ret)#['ab']

跟着教程敲代码练习:

"""第一类元字符 . ^ $ * + ? {}"""

importre""". 匹配除了 \n 之外的任意字符,一个 . 只能匹配一个字符"""re.findall("alex","djkalfjioealexieou") ##['alex']

re.findall("a..x",'jowutojoauixuoero') #['auix']

re.findall("a...x",'jowutojoauixuoero') #[]

"""^ 开头匹配"""re.findall("^a...x",'jowutojoauixuoero') #[]

re.findall("^j..u",'jowutojowuixuoero') #['jowu']

re.findall("j..u",'jowutojowuixuoero') #['jowu', 'jowu']

"""$ 结尾匹配"""re.findall("j..u$",'jowutojowuixuoejrou') #['jrou']

re.findall("j..u$",'jowutojowuixuoejrou$') #[]

"""* 紧挨着的字符 匹配0~无穷次"""

"""+ 紧挨着的字符 匹配1~无穷次"""re.findall("alex*","uoghkalexxx") #['alexxx']

re.findall("alex+","uoghkalexxx") #['alexxx']

re.findall("alex*","uoghkale") #['ale']

re.findall("alex+","uoghkale") #[]

"""? 紧挨着的字符 匹配0~1"""re.findall("alex?","uoghkale") #['ale']

re.findall("alex?","uoghkalex") #['alex']

re.findall("alex?","uoghkalexxxx") #['alex']

"""{} 是上面 * + ? 的集合,并且可自定义

{0,} <===> *

{1,} <===> +

{0,1} <===> ?

{1,6} 1 2 3 4 5 6 都可以"""re.findall("alex{6}","uoghkalexxxxxx") #['alexxxxxx']

re.findall("alex{0,6}","uoghkalexxx") #['alexxx']

re.findall("alex{0,6}","uoghkale") #['ale']

re.findall("alex{0,1}","uoghkale") #['ale']

re.findall("alex{0,1}","uoghkalex") #['alex']

#惰性匹配 在元字符后面加上 ?

re.findall("alex*?","uoghkalexxxx") #['ale']

re.findall("alex+?","uoghkalexxxx") #['alex']

re.findall("alex+","uoghkalexxxx") #['alexxxx']

我的理解

元字符之字符集[]:

(1) 常用来指定一个字符集,如[abc]匹配:a或b或c

(2) 元字符. * ? + ^ $ 在[]中不起所用,比如:[a+]匹配:a或+

但注意:在方括号中:要匹配转义符“\”本身,要用:\\;要匹配方括号开头的^符本身,要用:\^;要匹配-字符,需要用:\-

(3) 补集匹配:[^a],匹配非a的一个字符,^在[ ]中表示取非

(4) 匹配连续字符:[a-zA-Z0-9],匹配大小写英文字母和数字

#--------------------------------------------字符集[]

ret=re.findall('a[bc]d','acd')print(ret)#['acd']

ret=re.findall('[a-z]','acd')print(ret)#['a', 'c', 'd']

ret=re.findall('[.*+]','a.cd+')print(ret)#['.', '+']

#在字符集里有功能的符号: - ^ \

ret=re.findall('[1-9]','45dha3')print(ret)#['4', '5', '3']

ret=re.findall('[^ab]','45bdha3')print(ret)#['4', '5', 'd', 'h', '3']

ret=re.findall('[\d]','45bdha3')print(ret)#['4', '5', '3']

跟着教程敲代码练习:

"""[] 中:^ 非 ,- 表示从。。到。。 a-z 所有小写字母,\ 转义 \( 就表示左括号。

其他的元字符失去意义,如 * 不表示(0-无穷),()就只是表示括号"""ret= re.findall('a[bc]d', 'acd') #匹配 abd 或 acd

print(ret) #['acd']

ret= re.findall('[a-z]', 'acd') #一个字符 从a到z

print(ret) #['a', 'c', 'd']

ret= re.findall('[.*+]', 'a.cd+') #* 失去特殊意义 就表示一个 *

print(ret) #['.', '+']

#在字符集里有功能的符号: - ^ \

ret= re.findall('[1-9]', '45dha3')print(ret) #['4', '5', '3']

ret= re.findall('[^ab]', '45bdha3')print(ret) #['4', '5', 'd', 'h', '3']

ret= re.findall('[\d]', '45bdha3')print(ret) #['4', '5', '3']

我的理解

#一个特殊案例:匹配表达式里面 最内层括号(13-6)

re.findall("\([^()]*\)","12+(34*6+2-5*(13-6))")    #['(13-6)']

元字符之转义符 \

反斜杠后边跟元字符去除特殊功能,比如 \.

反斜杠后边跟普通字符实现特殊功能,比如 \d

\d  匹配任何十进制数;它相当于类 [0-9]。

\D 匹配任何非数字字符;它相当于类 [^0-9]。

\s  匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。

\S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。

\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。

\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]

\b  匹配一个特殊字符边界,比如空格 ,&,#等

ret=re.findall('I\b','I am LIST')print(ret)#[]

ret=re.findall(r'I\b','I am LIST')print(ret)#['I']

r'I\b' 其中 r=raw 表示原始的 未经处理的

re.findall(r'I\b','I am LIST') #r'I\b' 要先经过Python解释器编译 然后传递给re模块,re模块处理 \b 匹配到 空格

现在我们聊一聊 \ ,先看下面两个匹配:

#-----------------------------eg1:

importre

ret=re.findall('c\l','abc\le')print(ret)#[]

ret=re.findall('c\\l','abc\le')print(ret)#[]

ret=re.findall('c\\\\l','abc\le')print(ret)#['c\\l']

ret=re.findall(r'c\\l','abc\le')print(ret)#['c\\l']

#-----------------------------eg2:#之所以选择\b是因为\b在ASCII表中是有意义的

m = re.findall('\bblow', 'blow')print(m)

m= re.findall(r'\bblow', 'blow')print(m)

由于Python的字符串本身也用 \转义,所以要特别注意:

s = 'ABC\\-001' #Python的字符串#对应的正则表达式字符串变成:#'ABC\-001'

因此我们强烈建议使用Python的 r前缀,就不用考虑转义的问题了:

s = r'ABC\-001' #Python的字符串#对应的正则表达式字符串不变:#'ABC\-001'

元字符之分组 ()

(?P\d+)     有名分组 可以通过ret.group('分组名') 取得匹配结果

m = re.findall(r'(ad)+', 'add')print(m) #ad

ret=re.search('(?P\d{2})/(?P\w{3})','23/com')print(ret.group()) #23/com

print(ret.group('id')) #23

##'(?P\d{2})/(?P\w{3})' ?P 分组 组名为ip, \d{2} 匹配后面两位整数#(?P\w{3}) ?P 分组 组名为name,\w{3} 匹配3位 大小写字母 数字 下划线

>>> re.search(r'(.*).*

(.*)

',s).group(1)'更多'

>>> re.search(r'(.*).*

(.*)

',s).group(2)'dfsl'

>>> ss = re.search(r'(?P.*).*

(?P.*)

',s)>>> ss.group('txt')'更多'

>>> ss.group('txt2')

练习:

>>> re.findall(r'(abc)+','adklnvkaj45d6kasdfeabcwoibcfabcabcabcdf')

['abc', 'abc']>>> re.findall(r'abc+','adklnvkaj45d6kasdfeabcwoibcfabcabcabcdf')

['abc', 'abc', 'abc', 'abc']>>> re.findall(r'(abc)+','abcabcabcabc')

['abc']>>> re.findall(r'(abc)*','abcabcabcabc')

['abc', '']>>> re.findall(r'(ab)+','abcabcabcabc')

['ab', 'ab', 'ab', 'ab']>>> re.findall(r'(abc)+','abcabcabcabc')

['abc']>>> re.findall(r'(abc)+','abcccccc')

['abc']>>> re.findall(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56')

['xiong', 'wang', 'zhang', 'sun']>>> re.search(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56')<_sre.sre_match object span="(0," match="xiong26">

>>> re.search(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56').group()'xiong26'

>>> re.search(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56').group("name")'xiong'

>>> re.search(r'(?P[a-z]+)(?P\d+)','xiong26wang33zhang23sun56').group("name")'xiong'

>>> re.search(r'(?P[a-z]+)(?P\d+)','xiong26wang33zhang23sun56').group("age")'26'

cmd执行

元字符之|

ret=re.search('(ab)|\d','rabhdg8sd')print(ret.group())#ab

re模块下的常用方法

#1

re.findall('a', 'alvin yuan') #返回所有满足匹配条件的结果,放在列表里#2

re.search('a', 'alvin yuan').group() #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以#通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

#3

re.match('a', 'abc').group() #同search,不过要在字符串开始处进行匹配,相当于re.search('^','')

#4

ret = re.split('[ab]', 'abcd') #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割

print(ret) #['', '', 'cd']

#5

ret = re.sub('\d', 'A', 'alvin5yuan6', 1) ## 替换 数字 替换为 A , 只替换第一个

print(ret) #alvinAyuan6

ret = re.subn('\d', 'A', 'alvin5yuan6') #将替换结果 和 替换个数 返回为一个元组

print(ret) #('alvinAyuanA', 2)

#6

obj = re.compile('\d{3}') ## 编译,如果使用多次匹配规则 效率就体现出来了

ret = obj.search('abc123eeee')print(ret.group()) #123

处理大量数据,匹配结果返回一个迭代器

importre

ret=re.finditer('\d','ds3sy4784a')print(ret) #

print(next(ret).group())print(next(ret).group())

注意:

ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')print(ret) #['oldboy'] 这是因为findall会优先把匹配结果分组里内容返回,如果想要匹配结果,取消权限即可

ret= re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')print(ret) #['www.oldboy.com']

补充练习题:

>>> importre>>> re.findall('\d+','nka15640-8dasgwe-96dagv-6')

['15640', '8', '96', '6']>>> re.findall('^\d+','nka15640-8dasgwe-96dagv-6')

[]>>> re.findall('[^-]\d+','nka15640-8dasgwe-96dagv-6')

['a15640', '96']>>> re.findall('\d{3}\s+\d{3,8}','sdfag123 7845agewgv')

['123 7845']>>> re.findall('\d+@$','1351655382@qq.com')

[]>>> re.findall('\d+','1351655382@qq.com')

['1351655382']>>> re.findall(r'ka|b','adklnvkj45d6kaewoib')

['ka', 'b']>>> re.findall(r'ka|b','adklnvkj45d6ksdfewoibfadf')

['b']>>> re.findall(r'ka|bc','adklnvkaj45d6kasdfewoibcfadf')

['ka', 'ka', 'bc']>>> re.findall(r'(abc)+','adklnvkaj45d6kasdfeabcwoibcfabcabcabcdf')

['abc', 'abc']>>> re.findall(r'abc+','adklnvkaj45d6kasdfeabcwoibcfabcabcabcdf')

['abc', 'abc', 'abc', 'abc']>>> re.findall(r'(abc)+','abcabcabcabc')

['abc']>>> re.findall(r'(abc)*','abcabcabcabc')

['abc', '']>>> re.findall(r'(ab)+','abcabcabcabc')

['ab', 'ab', 'ab', 'ab']>>> re.findall(r'(abc)+','abcabcabcabc')

['abc']>>> re.findall(r'(abc)+','abcccccc')

['abc']>>> re.findall(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56')

['xiong', 'wang', 'zhang', 'sun']>>> re.search(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56')<_sre.sre_match object span="(0," match="xiong26">

>>> re.search(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56').group()'xiong26'

>>> re.search(r'(?P[a-z]+)\d+','xiong26wang33zhang23sun56').group("name")'xiong'

>>> re.search(r'(?P[a-z]+)(?P\d+)','xiong26wang33zhang23sun56').group("name")'xiong'

>>> re.search(r'(?P[a-z]+)(?P\d+)','xiong26wang33zhang23sun56').group("age")'26'

>>> re.findall('(ab)|\d','rabhdg8sd')

['ab', '']>>> re.findall('(ab)|\d+','rabhdg8sd')

['ab', '']>>> re.findall('(ab)|\d+','rab632hdg8sd')

['ab', '', '']>>> re.findall('(ab)|\d','rab632hdg8sd')

['ab', '', '', '', '']>>> re.findall('(ab)|\d+','rab632hdg8sd')

['ab', '', '']>>> re.findall('(ab).*\d+','rab632hdg8sd')

['ab']>>> re.match('a', 'abc').group()'a'

>>> re.match('a', 'abcadfa').group()'a'

>>>

####################split分割

>>> re.split(' ','hello world xiong')

['hello', 'world', 'xiong']>>> re.split('[ |]','hello world|xiong')

['hello', 'world', 'xiong']>>> re.split('[ab]','vnklaouojbouhg')

['vnkl', 'ouoj', 'ouhg']>>> re.split('[ab]','auouabuobuo')

['', 'uou', '', 'uo', 'uo']>>> re.split('[ab]','asdabcd')

['', 'sd', '', 'cd']>>> re.split('[ab]','abc')

['', '', 'c']>>>

>>>############# '替换'

>>> re.sub('\d+','A','as451da23bc23d5dae')'asAdaAbcAdAdae'

>>> re.sub('\d','A','as451da23bc23d5dae')'asAAAdaAAbcAAdAdae'

>>> re.sub('\d','A','as451da23bc23d5dae',3)'asAAAda23bc23d5dae'

>>> re.sub('\d','A','as451da23bc23d5dae',2)'asAA1da23bc23d5dae'

>>> re.subn('\d','A','as451da23bc23d5dae')

('asAAAdaAAbcAAdAdae', 8)>>>

###########compile编译

>>> com = re.compile("\d+")>>> com.findall("uoihja37jdaogj230ldaoje")

['37', '230']>>>

>>> re.findall("\d","af7nka89wejojk03oajag")

['7', '8', '9', '0', '3']>>> re.finditer("\d","af7nka89wejojk03oajag")

>>> ret = re.finditer("\d","af7nka89wejojk03oajag")>>> ret.__next__()<_sre.sre_match object span="(2," match="7">

>>> ret.__next__().group()'8'

>>>#############结果返回为一个迭代器

>>> ret = re.finditer("www\.(baidu|163)\.com","af7nkawww.baidu.com89wejojk03oajag")>>> re.finditer("www\.(baidu|163)\.com","af7nkawww.baidu.com89wejojk03oajag")

###################匹配结果优先返回为匹配到的分组内容

>>> re.findall("www\.(baidu|163)\.com","af7nkawww.baidu.com89wejojk03oajag")

['baidu']>>> re.findall("www\.(?:baidu|163)\.com","af7nkawww.baidu.com89wejojk03oajag")

['www.baidu.com']

练习

补充1:

importreprint(re.findall("\w+)>\w+(?P=tag_name)>","

hello

"))print(re.search("\w+)>\w+(?P=tag_name)>","

hello

"))print(re.search(r"\w+\1>","

hello

"))

View Code

补充2:

#匹配出所有的整数

importre#ret=re.findall(r"\d+{0}]","1-2*(60+(-40.35/5)-(-4*3))")

ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")

ret.remove("")print(ret)

View Code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值