python标准库之正则表达式

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#-*- coding:utf-8 -*-
import re
'''
正则表达式会搜索匹配特定模式的语句,非常实用
'''
#========================================================
# Level1:基本语句
# 4种定位标记:锚点、数量符、运算符、字符类
#========================================================

# 1、锚点:^和$
'''
^ 代表开头
$ 代表结尾
xyz 类似这样不加括号的文本代表特定的字符串
'''
print('LV1.1----------------------')
string11 = 'this is'
result11 = re.findall('^this', string11, flags=0) # 匹配开头的this
result12 = re.findall('is$', string11, flags=0) # 匹配末尾的is
result13 = re.findall('is', string11, flags=0) # 匹配所有的is
string12 = '2004-959-559 # 这是一个国外电话号码'
result14 = re.sub(r'#.*$', "", string12) # 删除字符串中的 Python注释
print(result11)
print(result12)
print(result13)
print(result14)

# 2、数量符:*、+、?和 {}
'''
* 大于等于0个数量---贪婪(贪心)
+ 至少1次---占有
? 至多1次---懒惰(勉强)
*? 懒惰限定符,重复0次或更多次但尽量少重复
+? 懒惰限定符,重复1次或更多次但尽量少重复
?? 懒惰限定符,重复0次或1次但尽可能少重复
c{2} 两个c
c{2,} 两个或更多个c
c{2,5} 两个到5个c
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 懒惰限定符,重复n次以上但尽可能少重复
'''
print('LV1.2----------------------')
string21 = '18155825579'
result21 = re.findall('1[3-8]\d{9}', string21, flags=0) # ab开头,后面有两个以上c
string22 = 'aaaaaaaa'
result22 = re.findall('a{1,}?', string22, flags=0)
print(result21)
print(result22)

# 3、或运算符:|
print('LV1.3----------------------')
'''
a|b a或者b
'''
string31 = 'typejb5shtypeabab'
result31 = re.findall('type=1|ab', string31, flags=0)
print(result31)

# 4、字符类:d、w、s 和 .
print('LV1.4----------------------')
'''
\d 匹配数字 =[0-9]
\D 匹配非数字 =[^0-9]
\w 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字 =[a-zA-Z0-9]
\W 匹配特殊字符,即非字母、非数字、非汉字、非_ =[^\w]
\s 匹配空白(包括空格、换行、tab缩进等) =[_\r\t\n\f]
\S 匹配非空白 =[^\s]
\. 匹配任意1个字符(除了\n)
'''
string41 = '嫦娥1号,$10$290'
result41 = re.findall('嫦娥\d号', string41, flags=0)
result42 = re.findall('\$\d+', string41, flags=0) # 匹配前面有$符号的数字,因为$已经有含义一定要加转义!
print(result41)
print(result42)

#========================================================
# Level2:中级语句
#========================================================

# 1、分组和捕获:()
print('LV2.1----------------------')
'''
()表示捕获分组,只输出捕获到的值
(?:)表示非捕获分组,区别在于不会只输出捕获到的值
'''
string51 = '1234abc123ABC'
result51 = re.findall('(\d+)[a-z]+(\d+)', string51, flags=0)
result52 = re.findall('(?:\d+)[a-z]+(?:\d+)', string51, flags=0)
print(result51)
print(result52)

# 2、方括弧表达式:[]
print('LV2.2----------------------')
'''
[abc] 匹配一个a、b或c,同a|b|c
[a-c] 匹配一个a、b或c,同a|b|c
[a-fA-F0-9] 匹配一个代表16进制数字的字符,不区分大小写
[^a-zA-Z] 不在[]中的字符,其中^为否定表达式。左侧含义是匹配一个不带a到z或A到Z的字符
注意:在方括弧内,所有特殊字符(包括反斜杠)都会失去它们应有的意义。
'''
string61 = '<div>1234abc</div>'
result61 = re.findall('\d{3,}[a-z]', string61, flags=0)
result62 = re.findall('<div>(\d+[a-z]{3})</div>', string61, flags=0)
result63 = re.findall('[^a-z<>/]+', string61, flags=0) # 匹配不是a-z,<,>,/的内容
print(result61)
print(result62)
print(result63)

#========================================================
# Level3:高级语句
#========================================================

# 1、边界符B
print('LV3.1----------------------')
'''
\b 不会消耗任何字符只匹配一个位置,常用于匹配单词边界(单词划分以空格为基础,既然没有空格,必然没有两个单词)
\B 匹配不是单词开头或结束的位置
总结:^ 和 $ 是描述整个字符串的边界,\b 和 \B 是描述字符串中的单词边界
'''
string71 = 'hover ve'
result71 = re.findall(r'^\w+\s\bve\b', string71, flags=0)
string72 = 'hover'
result72 = re.findall(r'^.+\Bve\B', string72, flags=0)
print(result71)
print(result72)

# 2、前向匹配和后向匹配:(?=) 和 (?<=)
'''
d(?=r) 只有在后面跟着r的时候才匹配d,但是r并不会成为整个正则表达式匹配的一部分
(?<=r)d 只有在前面跟着r时才匹配d,但是r并不会成为整个正则表达式匹配的一部分
d(?!r) 只有在后面不跟着r的时候才匹配d,但是r并不会成为整个正则表达式匹配的一部分
(?<!r)d 只有在前面不跟着r时才匹配d,但是r并不会成为整个正则表达式匹配的一部分
'''
print('LV3.2----------------------')
string81 = 'exp1exp2exp1'
result81 = re.findall('exp1(?=exp2)', string81, flags=0) # 查找exp2前面的exp1
result82 = re.findall('(?<=exp2)exp1', string81, flags=0) # 查找exp2后面的exp1
string82 = '<div>1234abc</div><div>2234abc</div>'
result83 = re.findall('(?<=<div>).*?(?=</div>)', string82, flags=0)
print(result81)
print(result82)
print(result83)