欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

s21day26 python笔记

程序员文章站 2022-03-20 20:25:35
s21day26 python笔记 一、内容回顾及补充 正则表达式 转义符:\ 正则表达式中的转义符在python的字符串中也刚好有转移的作用 但是正则表达式中的转义符和字符串中的转义符并没关系,且还容易有冲突 为了避免这种冲突,我们所有的正则都以在工具中的测试结果为结果 然后只需要在正则和待匹配的 ......

s21day26 python笔记

一、内容回顾及补充

  • 正则表达式
    • 转义符: - 正则表达式中的转义符在python的字符串中也刚好有转移的作用
      • 但是正则表达式中的转义符和字符串中的转义符并没关系,且还容易有冲突
      • 为了避免这种冲突,我们所有的正则都以在工具中的测试结果为结果
      • 然后只需要在正则和待匹配的字符串外面都加r即可

二、re模块

正则模块

  1. re.findall:会匹配字符串中所有符合规则的项,并返回一个列表,如果没匹配到,返回空列表

    import re
    ret = re.findall('\d+','alex83')
    print(ret)
    # findall 会匹配字符串中所有符合规则的项
    # 并返回一个列表
    # 如果未匹配到返回空列表
  2. re.search:如果匹配到,返回一个对象,用group取值,如果没匹配到,返回none,不能用group

    import re
    ret = re.search('\d+','alex83')
    print(ret)                 # 如果能匹配上返回一个对象,如果不能匹配上返回none
    if ret:
        print(ret.group())     # 如果是对象,那么这个对象内部实现了group,所以可以取值
                               # 如果是none,那么这个对象不可能实现了group方法,所以报错
    # 会从头到尾从带匹配匹配字符串中取出第一个符合条件的项
    # 如果匹配到了,返回一个对象,用group取值
    # 如果没匹配到,返回none,不能用group
  3. re.match:match = search + ^正则

    import re
    ret = re.match('\d','alex83') == re.match('^\d','alex83')
    print(ret)
    # 会从头匹配字符串中取出从第一个字符开始是否符合规则
    # 如果符合,就返回对象,用group取值
    # 如果不符合,就返回none
  4. re.finditer:在查询的结果超过1个的情况下,能够有效的节省内存,降低空间复杂度,从而也降低了时间复杂度

    import re
    ret = re.finditer('\d','safhl02urhefy023908'*20000000)  # ret是迭代器
    for i in ret:    # 迭代出来的每一项都是一个对象
        print(i.group())  # 通过group取值即可
  5. 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())
  6. re.split:利用正则规则进行切割

    import re
    ret = re.split('\d(\d)','alex83wusir74taibai')  # 默认自动保留分组中的内容
    print(ret)
  7. 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模块

  1. 关于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))   # 取第二个分组中的内容
  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分组中的内容
  3. 引用分组:(?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'
  4. 分组和findall:默认findall 优先显示分组内的内容,取消分组优先显示 :(?:正则)

    import re
    ret = re.findall('\d(\d)','aa1alex83')
    # findall遇到正则表达式中的分组,会优先显示分组中的内容
    print(ret)
    
    # 取消分组优先显示:
    ret = re.findall('\d+(?:\.\d+)?','1.234+2')
    print(ret)
  5. 有的时候我们想匹配的内容包含在不相匹配的内容当中,这个时候只需要把不想匹配的先匹配出来,再通过手段去掉

    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()