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

 

posted @ 2019-07-03 05:58  尹正杰  阅读(202)  评论(0编辑  收藏  举报