Python的正则表达式re模块
Python的正则表达式(re模块)
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
Python使用re模块提供了正则表达式处理的能力。如果对正则表达式忘记的一干二净的话,可以花费几分钟时间在网上概览一下正则表达式基础,也可以参考我之前的笔记:https://www.cnblogs.com/yinzhengjie/p/11112046.html。
一.常量
多行模式:
re.M
re.MULTILINE
单行模式:
re.S
re.DOTAL
忽略大小写:
re.I
re.IGNORECASE
忽略表达式中的空白字符:
re.X
re.VERBOSE
二.单次匹配
1>.match方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 result = re.match("b",src) #match匹配从字符串的开头匹配,找到第一个就不找了,返回match对象。 15 print(1,result) 16 17 result = re.match("a",src) #没找到,返回None 18 print(2,result) 19 20 result = re.match("^a",src,re.M) #依然从头开始找,多行模式没有用 21 print(3,result) 22 23 result = re.match("^a",src,re.S) #依然从头开始找 24 print(4,result) 25 26 """ 27 设定flags,编译模式,返回正则表达式对象regex。第一个参数就是正则表达式字符串(pattern),flags是选项。正则表达式需 28 要被编译,为了提高效率,这些编译后的结果被保存,下次使用同样的pattern的时候,就不需要再次编译。 29 re的其它方法为了提高效率都调用了编译方法,就是为了提速。 30 """ 31 regex = re.compile("a",flags=0) #先编译,然后使用正则表达式对象 32 result = regex.match(src) #依然从头开始找,regex对象match方法可以设置开始位置和结束位置,依旧返回match对象。 33 print(5,regex) 34 35 result = regex.match(src,15) #把索引15作为开始找 36 print(6,result) 37 38 39 #以上代码执行结果如下: 40 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 41 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 42 43 1 <re.Match object; span=(0, 1), match='b'> 44 2 None 45 3 None 46 4 None 47 5 re.compile('a') 48 6 <re.Match object; span=(15, 16), match='a'>
2>.serach方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 result = re.search("a",src) #从头搜索知道第一个匹配,返回mathc对象 15 print(1,result) 16 17 regex = re.compile("b") 18 result = regex.search(src,1) 19 print(2,result) 20 21 regex = re.compile("^b",re.M) 22 result = regex.search(src) #regex对象search方法可以重设定开始位置和结束位置,返回mathc对象 23 print(3,result) 24 25 result = regex.search(src,8) 26 print(4,result) 27 28 29 30 #以上代码执行结果如下: 31 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 32 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 33 34 1 <re.Match object; span=(8, 9), match='a'> 35 2 <re.Match object; span=(7, 8), match='b'> 36 3 <re.Match object; span=(0, 1), match='b'> 37 4 <re.Match object; span=(11, 12), match='b'>
3>.fullmatch方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 result = re.fullmatch("bag",src) 15 print(1,result) 16 17 regex = re.compile("bag") 18 result = regex.fullmatch(src) 19 print(2,result) 20 21 result = regex.fullmatch(src,7) 22 print(3,result) 23 24 result = regex.fullmatch(src,7,10) #整个字符串和正则表达式匹配,多了少了都不行!当然,也可以指定搜索的起始,结束位置,找到了返回mathc对象,找不着就返回None 25 print(4,result) 26 27 28 29 30 #以上代码执行结果如下: 31 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 32 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 33 34 1 None 35 2 None 36 3 None 37 4 <re.Match object; span=(7, 10), match='bag'>
三.全文搜索
1>.findall方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 result = re.findall("b",src) #对整个字符串,从左至右匹配,返回所有匹配项的列表 15 print(1,result) 16 17 regex = re.compile("^b") 18 result = regex.findall(src) #功能同上,只不过使用的是编译后的pattern,效率相对较高。 19 print(2,result) 20 21 regex = re.compile("^b",re.M) 22 result = regex.findall(src,7) 23 print(3,result) 24 25 result = regex.findall(src,7,10) 26 print(4,result) 27 28 regex = re.compile("^b",re.S) 29 result = regex.findall(src) 30 print(5,result) 31 32 33 34 #以上代码执行结果如下: 35 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 36 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 37 38 1 ['b', 'b', 'b'] 39 2 ['b'] 40 3 ['b', 'b'] 41 4 ['b'] 42 5 ['b']
2>.finditer方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 regex = re.compile("^b",re.M) 15 result = regex.finditer(src) #对整个字符串,从左至右匹配,返回所有匹配项,返回迭代器,注意每次迭代返回的是match对象。 16 print(type(result)) 17 18 r = next(result) 19 print(type(r),r) 20 print(r.start(),r.end(),src[r.start():r.end()]) 21 22 r = next(result) 23 print(type(r),r) 24 print(r.start(),r.end(),src[r.start():r.end()]) 25 26 27 28 #以上代码执行结果如下: 29 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 30 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 31 32 <class 'callable_iterator'> 33 <class 're.Match'> <re.Match object; span=(0, 1), match='b'> 34 0 1 b 35 <class 're.Match'> <re.Match object; span=(7, 8), match='b'> 36 7 8 b
四.匹配替换
1>.sub方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 regex = re.compile("b\wg") 15 result = regex.sub("yinzhengjie",src) #使用pattern对字符串string进行匹配,对匹配项使用"yinzhengjie"替换。我们替换的数据类型可以为string,bytes,function 16 print(1,result) 17 18 print("*" * 20 + "我是分割线" + "*" * 20) 19 20 result = regex.sub("jason",src,1) #我们这里可以指定只替换1次哟~ 21 print(2,result) 22 23 24 25 26 #以上代码执行结果如下: 27 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 28 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 29 30 1 bottle 31 yinzhengjie 32 yinzhengjie 33 apple 34 ********************我是分割线******************** 35 2 bottle 36 jason 37 big 38 apple
2>.subn方法
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 regex = re.compile("\s+") 15 result = regex.subn("\t",src) #功能和sub类似,只不过它返回的是一个元组,即被替换后的字符串及替换次数的元组。 16 print(result) 17 18 19 20 21 #以上代码执行结果如下: 22 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 23 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 24 25 ('bottle\tbag\tbig\tapple', 3)
五.分割字符串
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """ 9 os.path.abspath(path) 10 normpath(join(os.getcwd(),path)). 11 """ 12 13 print(src.split()) #字符串的分割函数split,太难用,不能指定多个字符串进行分割。 14 print(re.split("[\.()\s,]+",src)) #正则表达式的re模块就可以支持多个字符串进行分割哟~ 15 16 17 18 #以上代码执行结果如下: 19 ['os.path.abspath(path)', 'normpath(join(os.getcwd(),path)).'] 20 ['', 'os', 'path', 'abspath', 'path', 'normpath', 'join', 'os', 'getcwd', 'path', '']
六.分组
1>.分组概述
使用小括号的pattern捕获的数据被放到了组group中。
match,search函数可以返回match对象;findall返回字符串列表;finditer返回一个个match对象。
如果pattern中使用了分组,如果有匹配的结果,会在match对象中。
1>.使用group(N)方式返回对应分组,1到N是对应的分组,0返回整个匹配的字符串,N不写缺省为0;
2>.如果使用了命名分组,可以使用group('name')的方式取分组
3>.也可以使用groups返回所有组
4>.groupdict()返回所有命名的分组
2>.分组代码案例
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 regex = re.compile("(b\w+)") 15 result = regex.match(src) #从头匹配一次 16 print(type(result)) 17 print(1,"match",result.groups()) 18 19 result = regex.search(src,1) #从指定位置向后匹配一次 20 print(2,"search",result.groups()) 21 22 23 24 25 #以上代码执行结果如下: 26 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 27 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 28 29 <class 're.Match'> 30 1 match ('bottle',) 31 2 search ('bag',)
3>.命名分组
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 import re 7 8 src = """bottle\nbag\nbig\napple""" 9 10 for i,c in enumerate(src,1): 11 print((i-1,c),end="\n" if i % 10 == 0 else " ") 12 print() 13 14 regex = re.compile("(b\w+)\n(?P<name2>b\w+)\n(?P<name3>b\w+)") 15 16 result = regex.match(src) 17 print(1,"match",result) 18 print(2,result.group(3),result.group(2),result.group(1)) 19 print(3,result.group(0).encode()) #有没有分组,都可以使用Match对象的group(0),因为0返回整个匹配字符串。 20 print(4,result.group("name2"),result.group("name3")) 21 print(5,result.groups()) 22 print(6,result.groupdict()) 23 24 print("*" * 20 + "我是分割线" + "*" * 20) 25 26 result = regex.findall(src) #如果有分组,fandall返回的是分组的内容,而不是匹配的字符串 27 for item in result: 28 print(type(item),item) 29 30 regex = re.compile("(?P<head>b\w+)") 31 result = regex.finditer(src) 32 33 print("*" * 20 + "我是分割线" + "*" * 20) 34 35 for item in result: 36 print(type(item),item,item.group(),item.group("head")) 37 38 39 #以上代码执行结果如下: 40 (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b') (8, 'a') (9, 'g') 41 (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a') (16, 'p') (17, 'p') (18, 'l') (19, 'e') 42 43 1 match <re.Match object; span=(0, 14), match='bottle\nbag\nbig'> 44 2 big bag bottle 45 3 b'bottle\nbag\nbig' 46 4 bag big 47 5 ('bottle', 'bag', 'big') 48 6 {'name2': 'bag', 'name3': 'big'} 49 ********************我是分割线******************** 50 <class 'tuple'> ('bottle', 'bag', 'big') 51 ********************我是分割线******************** 52 <class 're.Match'> <re.Match object; span=(0, 6), match='bottle'> bottle bottle 53 <class 're.Match'> <re.Match object; span=(7, 10), match='bag'> bag bag 54 <class 're.Match'> <re.Match object; span=(11, 14), match='big'> big big
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/11124145.html,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。