VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > 数据分析 >
  • python笔记26(正则表达式、re模块)

一、今日内容

python中的方法
python中的方法+正则表达式的新内容
#分组
#分组命名
#引用分组
#爬虫的小例子

1、转义符

如:\n--->\\n--->print('\\n')#\n
如:print('\\\\n')#\\n
print(r'\n')
print(r'\\n')
#正则表达式中的转义符在python的字符串中也刚好有转义的作用
#但是正则表达式中的转义和字符串中的转义符并没关系
#且还容易冲突
#为避免这种冲突
#我们所有的正则都以工具中的测试结果为结果
#然后只需要在正则和待匹配的字串外面的都加‘r’即可。
如:
printr'\n')
print(r'\\n')

2、re模块(findall,search,match)

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

re.match
ret=re.match('\d','6alex83')==re.match('^\d','6alex83')
print(ret)
print(ret.group())#6
#会从头匹配字符串中取出从第一个字符开始是否符合规则
#如果符合,就返回对象,用group取值。
#如果不符合,就返回none
#match=search+正则

3、re其他方法及拓展

1、时间复杂度,效率 compile
#在同一个正则表达式重复使用多次的时候使用能够减少时间开销。
2、空间复杂度,内存占用率  finditer
#在查询的结果超过1个情况下,能够有效的节省内存,降低空间复杂度,从而也降低了时间复杂度。
3、用户体验
大数据量的时候:
import re
ret=re.findall('\d','alhlajanlha12llhlajlmahlj4'*2000000)
print(ret)

=====
import re
ret=re.finditer('\d','alhlajanlha12llhlajlmahlj4'*2000000)
for i in ret:#迭代出来的每一项都是一个对象
	print(i.group())#通过group取值即可
    
 re.compile()
#\d正则表达式,---》字符串
#\d  str,循环str,找到所有的数字。

s = '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>' '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>'
ret=re.compile('\d+')
print(ret)
r1=ret.search('alex83')
print(r1)
print(r1.group())
ret.findall('wusu74')
ret.finditer('taibai40')
#finditer作用:
r3=ret.finditer('taibai40')
print(r3)
for i in r3:
    print(i.group())    
    
    
#re.sub
#re.split

import re

ret=re.split('\d+','alex83wusir74taibai50')#默认只保留分组中的内容
print(ret)
#['alex', 'wusir', 'taibai', ''],以数字分割,最后一个空字符,是50切割出来的。
	
import re

ret=re.split('(\d+)','alex83wusir74taibai50')
print(ret)
#['alex', '83', 'wusir', '74', 'taibai', '50', '']
ret=re.split('\d(\d)','alex83wusir74taibai50')
print(ret)
#['alex', '3', 'wusir', '4', 'taibai', '0', '']

import re
ret=re.sub('\d','D','alex83wusir74taibai50')
print(ret)
rett=re.subn('\d','D','alex83wusir74taibai50')
print(rett)

alexDDwusirDDtaibaiDD
('alexDDwusirDDtaibaiDD', 6)

总结:
findall 参数顺序和数据类型,返回值类型
search
match
compile
finditer
sub
subn

(1)、分组的概念和re模块

s1 = '<h1>wahaha</h1>'
s2 = '<a>wahaha ya wahaha</a>'

ret=re.search('<(\w+)>(.*?)</\w+>',s1)
print(ret)
print(ret.group())#默认为0,取所有
print(ret.group(1))#第一个分组
print(ret.group(2))#第二个分组
#另解方法:[a-z\d]+

分组命名方法:
s1 = '<h1>wahaha</h1>'
s2 = '<a>wahaha ya wahaha</a>'

ret=re.search('<(?P<tag>\w+)>(?P<cont>.*?)</\w+>',s1)
print(ret)
print(ret.group())#默认为0,取所有
print(ret.group("tag"))#tag分组
print(ret.group("cont"))#cont分组
分组命名:
(?P<名字>正则表达式)
引用分组(?P=组名)这个组中的内容必须完全和之前已经存在的组匹配到的内容一模一样。
引用分组:
s1=<h1>wahaha</h1>
ret=re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s1)
print(ret)
print(ret.group('tag'))

====

ret=re.search(r'<(\w+)>.*?</\1>',s1)#转义1(\1)的用法,如果不加r,\1为空。
print(ret)
print(ret.group(1))

总结:
splist
#会保留分组中应该被切割掉的内容
分组命名
(?P<命名>正则) search group('组名')
引用分组
(?P=组名)表示这个组中的内容必须和之前已经存在的一组匹配到的内容完全一致。
分组和findall
#默认findall优先显示分组内的内容
#取消分组优先显示(?:正则)

实例:

import re

ret=re.findall('\d(\d)','al1xel83')
#findall遇到正则表达式中的分组,会优先显示分组中的内容
print(ret)
ret0=re.findall('\d+(\.\d+)?','1.234+2')
print(ret0)
ret1=re.findall('\d+(?:\.\d+)?','1.234+2')
print(ret1)

['3']
['.234', '']
['1.234', '2']

#例题:
#有的时候我们想匹配的内容包含在不相匹配的内容当中,这个时候只需要把不想匹配的先匹配出来,再通过手段去掉。
import re
ret=re.findall("\d+\.\d+|\d","1-2*(60+(-40.35/5)-(-4*3))")
ret1=re.findall("\d+\.\d+|(\d)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
print(ret1)
ret1.remove('')
print(ret1)

(2)爬虫实例(爬豆瓣)

import requests
import re
N=0
header={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
for n in range(10):
    ret=requests.get('https://movie.douban.com/top250?start=%s&filter='%(N,),headers=header)
    content=ret.text
    parrter='<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>'
    res=re.finditer(parrter,content,flags=re.S)#如果使用findall,产生的内容放在列表中,列表每个元素都是一个元组。
    for i in res:
        print({'id':i.group('id'),'title':i.group('title'),'score':i.group('score'),'num':i.group('num')})
    N+=25

(3)递归和堆栈(实现三级菜单的返回和退出功能)

一、递归
menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}

def func_menu(menu):
    while True:
        for key in menu:
            print(key)
        nip=input("请输入:").strip()
        if nip.upper()=='Q':#退出
            return 'q'
        if nip.upper()=="B":#返回上级
            return #return 返回上一级
        elif menu.get(nip):
            flag=func_menu(menu[nip])
            if flag=='q':return 'q'

func_menu(menu)

二、堆栈

lst=[menu]
print(lst[-1].keys())
while lst:
    for key in lst[-1]:
        print(key)
    inp=input('>>>')
    if inp.upper()=='Q':break
    elif inp.upper()=='B':lst.pop()
    elif lst[-1].get(inp):
        lst.append(lst[-1][inp])

(4)使用listdir求文件夹大小

import os
path1=r'E:\新建文件夹\teaching_plan'
lst=[path1]
size=0
while lst:
    path=lst.pop()
    name_lst=os.listdir(path)
    for name in name_lst:
        full_name=os.path.join(path,name)
        if os.path.isdir(full_name):
            lst.append(full_name)
        elif os.path.isabs(full_name):
            size+=os.path.getsize(full_name)
print(size)
 

相关教程