1 ```python
2 知识脉络:
3 # 在python中使用正则表达式
4 # 转义符 : 在正则中的转义符 \ 在python中的转义符
5 # re模块
6 # findall search match
7 # sub subn split
8 # compile finditer
9 # python中的正则表达式
10 # findall 会优先显示分组中的内容,要想取消分组优先,(?:正则表达式)
11 # split 遇到分组 会保留分组内被切掉的内容
12 # search 如果search中有分组的话,通过group(n)就能够拿到group中的匹配的内容
13 # 正则表达式进阶
14 # 分组命名
15 # (?P<name>正则表达式) 表示给分组起名字
16 # (?P=name)表示使用这个分组,这里匹配到的内容应该和分组中的内容完全相同
17 # 通过索引使用分组
18 # \1 表示使用第一组,匹配到的内容必须和第一个组中的内容完全相同
19 ```
20
21
22
23 2021/11/15学习内容
24
25 1.学习大纲: a. re模块 b. 常用的方法
26
27 c. python中正则表达式的特点
28
29 d. time模块
30
31 e. random模块
32
33
34
35
36
37 a. re 模块 (1) 匹配 findall search match
38
39 (2) 替换 sub subn
40
41 (3) 切割 split
42
43 (4) 进阶方法 compile finditer
44
45 (1) 匹配.
46
47 ```python
48 import re
49 # 匹配一 findall (*****)
50 re.findall('正则表达式', '字符串')
51 返回值类型:'列表' 返回值个数:1个 返回值内容:如果匹配上了就返回一个列表对象如果匹配不上返回空列表
52 eg1:
53 ret1 = re.findall('\d+', '451355saddf5562') # 第一个是正则表达式,第二个参数是
54 print(ret1)
55 结果: ['451355', '5562'] 返回的是一个列表
56 ```
57
58 ```python
59 import re
60 # 匹配二 search (*****)
61 re.search('正则表达式', '字符串')
62 返回值类型: 正则表达式的结果对象 返回值个数: 1个 返回值内容: 如果匹配上了就返回对象 如果匹配不上就返回None
63 eg2:
64 ret2 = re.search('\d+', '45132132asdhask13212')
65 print(ret2)
66 print(ret2.group())
67 结果: <re.Match object; span=(10, 11), match='d'> 返回的是一个(正则匹配结果的)对象
68 结果: 45132132 # 只匹配一次结果,惰性机制
69 eg3: ret3 = re.search('\d+', 'sdferer')
70 print(ret3)
71 if ret3:print(ret3.group())
72 结果: None 因为没有匹配到结果,所有返回None
73 ```
74
75 ```python
76 import re
77 # 匹配三 match (**)
78 re.match('正则表达式', '字符串')
79 相当于 在search前面加^(只从开头位置匹配) 可以通过group()函数来查看返回的值 只匹配一次
80 ```
81
82 (2) 替换
83
84 ```python
85 import re
86 # 替换一. sub (***) replace 'sads021'.replace('021', 'h') 将021替换成h
87 re.sub('替换的方式:正则表达式', '替换的结果','要替换字符串','次数')
88 # 如果不指定次数 默认 全部替换
89 re.subn('正则表达式', '要替换的内容','字符串') 返回一个元组 ('字符串', '替换的次数') 相当于返回符合的个数
90 eg1:
91 ret = re.sub('\d+', 'h', 'sads021') 将021替换成h
92 print(ret)
93 结果: sadsh 将字符串中的021替换成h
94 eg2:
95 ret = re.sub('\d+', 'h', 'sads021sdaf021dsf021')
96 print(ret)
97 结果: sadshsdafhdsfh 将字符串中的021全部替换h
98 eg3:
99 ret = re.subn('\d+','h','sdf1313sfa564q6fads')
100 print(ret)
101 结果: ('sdfhsfahqhfads', 3) 返回的是一个元组 ('新的字符串', '替换的次数')
102 ```
103
104 (3) 切割
105
106 ```python
107 import re
108 # 切割 split(***)
109 返回的是一个列表
110 eg1:
111 ret = re.split('\d','alex83egon20taibai40')
112 print(ret)
113 结果: ['alex', '', 'egon', '', 'taibai', '', '']
114 eg2:
115 print('yuxin/23/'.split('/'))
116 结果: ['yuxin', '23', '']
117 eg3:
118 ret = re.split('\d+','alex83egon20taibai40')
119 print(ret)
120 结果: ['alex', 'egon', 'taibai', '']
121 eg4:
122 ret = re.split('(\d+)','alex83egon20taibai40')
123 print(ret)
124 结果: ['alex', '83', 'egon', '20', 'taibai', '40', '']
125 # 对比eg3和eg4 将正则表达式用分组阔起来 就可以显示切割的字符串
126 ```
127
128 (4) 进阶方法
129
130 ```python
131 # 进阶方法 - 爬虫\自动化开发
132 # compile ***** 时间效率
133 # re.findall('-0\.\d+|-[1-9]+(\.\d+)?','alex83egon20taibai40') --> python解释器能理解的代码 --> 执行代码
134 # ret = re.compile('-0\.\d+|-[1-9]\d+(\.\d+)?')
135 # res = ret.search('alex83egon-20taibai-40')
136 # print(res.group())
137 # 节省时间 : 只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率
138 ```
139
140 ```python
141 # finditer ***** 空间效率
142 # print(re.findall('\d','sjkhkdy982ufejwsh02yu93jfpwcmc'))
143 # ret = re.finditer('\d','sjkhkdy982ufejwsh02yu93jfpwcmc')
144 # for r in ret:
145 # print(r.group())
146 ```
147
148 c. python中正则表达式的特点
149
150 ```python
151 # 分组遇到findall
152 import re
153 eg1:
154 ret = re.findall('-0\.\d+|-[1-9]\d*(\.\d+)?','-1asdada-200')
155 print(ret)
156 结果: ['', ''] 当正则表达式中的分组遇到了findall会优先显示分组内匹配的内容 忽略其他分组外的匹配内容
157 eg2:
158 ret = re.findall('www.(baidu|oldboy).com','www.oldboy.com')
159 print(ret)
160 结果: ['oldboy'] 只会优先显示分组内匹配的内容,忽略分组外匹配的内容
161 # 如果解决这个问题 要求eg2中返回 www.oldboy.com
162 eg3:
163 ret = re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
164 print(ret)
165 结果: ['www.oldboy.com'] 只需要在分组括号内前面加?: (?:....) 就可以取消分组优先显示
166 ```
167
168 ```python
169 # 分组遇见search
170 # ret = re.search('\d+(.\d+)(.\d+)(.\d+)?','1.2.3.4-2*(60+(-40.35/5)-(-4*3))')
171 # print(ret.group()) # 没有参数默认返回 整个匹配值
172 # print(ret.group(1))
173 # print(ret.group(2))
174 # print(ret.group(3))
175 # group(参数) 参数对应的就是读取括号 一一对应
176 ```
177
178 分组练习
179
180 ```python
181 import re
182 eg1:
183 ret = re.findall(r"\d+(?:\.\d+)?","1-2*(60+(-40.35/5)-(-4*3))")
184 print(ret)
185 结果: ['1', '2', '60', '40.35', '5', '4', '3'] 但是我们需求是只要整数
186 eg2:
187 ret = re.find(r"\d+(?:\.\d+)?|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
188 print(ret)
189 ret.remove('')
190 print(ret)
191 结果: ['1', '2', '60', '', '5', '4', '3']
192 结果: ['1', '2', '60', '5', '4', '3']
193 eg3:
194 ret = re.findall('>(\w+)<',r'<a>wahaha<\a>')
195 print(ret)
196 结果: ['wahaha']
197 eg4:
198 ret = re.search(r'<(\w+)>(\w+)</(\w+)>',r'<a>wahaha</b>')
199 print(ret.group())
200 print(ret.group(1))
201 print(ret.group(2))
202 结果 : <a>wahaha</b>
203 结果 : a
204 结果 : wahaha
205 ```
206
207 分组命名
208
209 ```python
210 import re
211 eg1:
212 ret = re.search("<(?P<name>\w+)>\w+</(?P=name)>","<h1>hello</h1>")
213 print(ret.group('name'))
214 结果: h1 给分组命名了 保证了第一个分组和第三个分组内容一样 在分组前面 ?P 表示给分组命名
215 eg2:
216 ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
217 print(ret.group(1))
218 结果: h1 也可以使用\1 表示内容与第一个分组一致
219 eg3:
220 ret = re.search(r'<(?P<tag>\w+)>(?P<c>\w+)</(\w+)>',r'<a>wahaha</b>')
221 print(ret.group())
222 print(ret.group('tag'))
223 print(ret.group('c'))
224 结果: <a>wahaha</b>
225 结果: a
226 结果: wahaha 也可以使用group('分组名字')来调用
227
228 ```
229