s21day26 python笔记
s21day26 python笔记
一、内容回顾及补充
- 正则表达式
- 转义符: - 正则表达式中的转义符在python的字符串中也刚好有转移的作用
- 但是正则表达式中的转义符和字符串中的转义符并没关系,且还容易有冲突
- 为了避免这种冲突,我们所有的正则都以在工具中的测试结果为结果
- 然后只需要在正则和待匹配的字符串外面都加r即可
- 转义符: - 正则表达式中的转义符在python的字符串中也刚好有转移的作用
二、re模块
正则模块
re.findall:会匹配字符串中所有符合规则的项,并返回一个列表,如果没匹配到,返回空列表
import re ret = re.findall('\d+','alex83') print(ret) # findall 会匹配字符串中所有符合规则的项 # 并返回一个列表 # 如果未匹配到返回空列表
re.search:如果匹配到,返回一个对象,用group取值,如果没匹配到,返回None,不能用group
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。import re ret = re.search('\d+','alex83') print(ret) # 如果能匹配上返回一个对象,如果不能匹配上返回None if ret: print(ret.group()) # 如果是对象,那么这个对象内部实现了group,所以可以取值 # 如果是None,那么这个对象不可能实现了group方法,所以报错 # 会从头到尾从带匹配匹配字符串中取出第一个符合条件的项 # 如果匹配到了,返回一个对象,用group取值 # 如果没匹配到,返回None,不能用group
re.match:match = search + ^正则
import re ret = re.match('\d','alex83') == re.match('^\d','alex83') print(ret) # 会从头匹配字符串中取出从第一个字符开始是否符合规则 # 如果符合,就返回对象,用group取值 # 如果不符合,就返回None
re.finditer:在查询的结果超过1个的情况下,能够有效的节省内存,降低空间复杂度,从而也降低了时间复杂度
import re ret = re.finditer('\d','safhl02urhefy023908'*20000000) # ret是迭代器 for i in ret: # 迭代出来的每一项都是一个对象 print(i.group()) # 通过group取值即可
re.compile:在同一个正则表达式重复使用多次的时候使用能够减少时间的开销
import re ret = re.compile('\d+') r1 = ret.search('alex83') r2 = ret.findall('wusir74') r3 = ret.finditer('taibai40') for i in r3: print(i.group())
re.split:利用正则规则进行切割
import re ret = re.split('\d(\d)','alex83wusir74taibai') # 默认自动保留分组中的内容 print(ret)
re.sub / re.subn:利用正则规则进行替换
import re ret = re.sub('\d','D','alex83wusir74taibai',1) print(ret) # 'alexD3wusir74taibai' ret = re.subn('\d','D','alex83wusir74taibai') print(ret) # ('alexDDwusirDDtaibai', 4)
分组和re模块
关于group取值
import re ret = re.search('<(\w+)>(.*?)</\w+>',s1) print(ret) print(ret.group(0)) # group参数默认为0 表示取整个正则匹配的结果 print(ret.group(1)) # 取第一个分组中的内容 print(ret.group(2)) # 取第二个分组中的内容
分组命名:(?P 正则表达式)
import re ret = re.search('<(?P<tag>\w+)>(?P<cont>.*?)</\w+>',s1) print(ret) print(ret.group('tag')) # 取tag分组中的内容 print(ret.group('cont')) # 取cont分组中的内容
引用分组:(?P=组名) 这个组中的内容必须完全和之前已经存在的组匹配到的内容一模一样
import re # 方法一: s = '<h1>wahaha</h1>' ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s) print(ret.group('tag')) # 'h1' # 方法二: s = '<h1>wahaha</h1>' ret = re.search(r'<(\w+)>.*?</\1>',s) print(ret.group(1)) # 'h1'
分组和findall:默认findall 优先显示分组内的内容,取消分组优先显示 :(?:正则)
import re ret = re.findall('\d(\d)','aa1alex83') # findall遇到正则表达式中的分组,会优先显示分组中的内容 print(ret) # 取消分组优先显示: ret = re.findall('\d+(?:\.\d+)?','1.234+2') print(ret)
有的时候我们想匹配的内容包含在不相匹配的内容当中,这个时候只需要把不想匹配的先匹配出来,再通过手段去掉
import re ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))") print(ret) # ['1', '2', '60', '', '5', '4', '3'] ret.remove('') print(ret) # ['1', '2', '60', '5', '4', '3']
爬虫示例
# 方法一:
import re
import json
import requests
def parser_page(par,content):
res = par.finditer(content)
for i in res:
yield {'id': i.group('id'),
'title': i.group('title'),
'score': i.group('score'),
'com_num': i.group('comment_num')}
def get_page(url):
ret = requests.get(url)
return ret.text
pattern = '<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?' \
'<span class="rating_num".*?>(?P<score>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>'
par = re.compile(pattern,flags=re.S)
num = 0
with open('movie_info',mode = 'w',encoding='utf-8') as f:
for i in range(10):
content = get_page('https://movie.douban.com/top250?start=%s&filter=' % num)
g = parser_page(par,content)
for dic in g:
f.write('%s\n'%json.dumps(dic,ensure_ascii=False))
num += 25
# 方法二:进阶
import re
import json
import requests
def parser_page(par,content):
res = par.finditer(content)
for i in res:
yield {'id': i.group('id'),
'title': i.group('title'),
'score': i.group('score'),
'com_num': i.group('comment_num')}
def get_page(url):
ret = requests.get(url)
return ret.text
def write_file(file_name):
with open(file_name,mode = 'w',encoding='utf-8') as f:
while True:
dic = yield
f.write('%s\n' % json.dumps(dic, ensure_ascii=False))
pattern = '<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?' \
'<span class="rating_num".*?>(?P<score>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>'
par = re.compile(pattern,flags=re.S)
num = 0
f = write_file('move2')
next(f)
for i in range(10):
content = get_page('https://movie.douban.com/top250?start=%s&filter=' % num)
g = parser_page(par,content)
for dic in g:
f.send(dic)
num += 25
f.close()

更多精彩