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