re模块,递归函数
程序员文章站
2022-03-25 18:48:01
re模块: 递归的定义——在一个函数里再调用这个函数本身 ......
re模块:
#findall : 返回所有满足匹配条件的结果,放在列表里 import re ret = re.findall('a', 'eva egon yuan') print(ret) #结果 : ['a', 'a'] #search : 只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回none。 ret = re.search('a', 'eva egon yuan').group() print(ret) #结果 : 'a' # split 切割 import re ret = re.split('\d+','alex222wusir') print(ret)#['alex', 'wusir'] ret = re.split('(\d+)','alex222wusir') print(ret)#['alex', '222', 'wusir'] ret = re.split('\d(\d)\d','alex123wusir') print(ret)#['alex', '2', 'wusir'] #在匹配部分加上()之后所切出的结果是不同的,没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,这个在某些需要保留匹配部分的使用过程是非常重要的。 ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret) # ['', '', 'cd'] # sub 替换 ret = re.sub('\d+','h','alex123wusir456') print(ret)#alexhwusirh ret = re.sub('\d+','h','alex123wusir456',1) #将数字替换成'h',参数1表示只替换1个 print(ret)#alexhwusir456 # subn ret = re.subn('\d+','h','alex123wusir456') #将数字替换成'h',返回元组(替换的结果,替换了多少次) print(ret)#('alexhwusirh', 2) 返回一个元组,2表示替换了2次. # match 在字符串开始处进行匹配,相当于在正则表达式前面人为的加上^,除此之外同search一样 ret = re.match('\d+','123eva456taibai') print(ret.group())#123 ret = re.search('^\d+','123eva456taibai') #以\d+开头的字符串 print(ret.group())#123 # 用户输入的内容匹配的时候,要求用户输入11位手机号码,^手机号正则表达式$,如^1[3-9]\d{9}$ ret = re.match('1[3-9]\d{9}$','13854888888') #match一般用来规定这个字符串必须是什么样的。解决检测一个输入的字符串是否合法的问题 print(ret.group())#13854888888 ret = re.search('^1[3-9]\d{9}$','13854888888') #search一般用来寻找这个字符串中是不是含有满足条件的子内容。解决从一个大文件中找到符合规则的内容的问题 print(ret.group())#13854888888 # compile --> 节省代码时间的工具 # 假如同一个正则表达式要被使用多次,可以节省了多次解析同一个正则表达式的时间。 ret = re.compile('\d+') #正则表达式可能很长,比如爬虫时 res1 = ret.search('alex37176') print(res1.group())#37176 res2 = ret.findall('alex37176') print(res2)#['37176'] obj = re.compile('\d{3}') #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字 ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串 print(ret.group()) #结果 : 123 # finditer --> 节省空间。在结果的内容非常多的情况下使用,节省内存。得到的是迭代器,迭代器内是结果变量。结果变量通过.group取值。 # findall 直接接返回列表,列表里是值 ret = re.finditer('\d+','agks1ak018093') #字符串特别长,比如是一个大文件时 for i in ret: print(i) print(i.group()) # <_sre.sre_match object; span=(4, 5), match='1'> # 1 # <_sre.sre_match object; span=(7, 13), match='018093'> # 018093 import re ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器 print(ret) # <callable_iterator object at 0x10195f940> print(next(ret).group()) #查看第一个结果 3 print(next(ret).group()) #查看第二个结果 4 print([i.group() for i in ret]) #查看剩余的左右结果 ['7', '8', '4'] #既节省时间,又节省空间: 先compile(如果没有重复使用同一个正则,也不能节省时间), 再finditer ret= re.compile('\d+') res = ret.finditer('agks1ak018as093') for r in res: print(r.group()) # 1 # 018 # 093 #1.功能 #2.性能 # 时间上 : # 你要完成一个代码所需要执行的代码行数 # 你在执行代码的过程中,底层程序是如何工作的 # 空间上: # 是占用了宝贵的内存条资源 # 影响程序的执行效率 #3. 用户体验 # 分组命名 # (?p<名字>正则表达式) # ret.group('名字') import re ret = re.search('\d(\d)\d(\w+?)(\d)(\w)\d(\d)\d(?p<name1>\w+?)(\d)(\w)\d(\d)\d(?p<name2>\w+?)(\d)(\w)', '123abc45678agsf_123abc45678agsf123abc45678agsf') print(ret.group('name1'))#agsf_123abc print(ret.group('name2'))#agsf # 分组命名的引用(引用分组):引用的是匹配到的内容,不是引用的正则表达式 分组命名 (?p<组名>正则表达式) 分组命名的引用 (?p=组名) 有的时候我们要匹配的内容是包含在不想要的内容之中的,只能先把不想要的内容匹配出来,然后再想办法从结果中去掉 #匹配标签: #可以在分组中利用?<name>的形式给分组起名字,获取的匹配结果可以直接用group('名字')拿到对应的值 import re ret = re.search("<(?p<tag_name>\w+)>\w+</(?p=tag_name)>","<h1>hello</h1>") print(ret.group('tag_name')) #结果 :h1 print(ret.group()) #结果 :<h1>hello</h1> import re exp= '<abc>akd7008&(&*)hgdwuih</abc>008&(&*)hgdwuih</abd>' #标签 ret= re.search('<(?p<tag>\w+)>.*?</(?p=tag)>',exp) # .*?非贪婪匹配 print(ret)#<_sre.sre_match object; span=(0, 30), match='<abc>akd7008&(&*)hgdwuih</abc>'> print(ret.group('tag'))#abc 要加引号 #如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致,获取的匹配结果可以直接用group(序号)拿到对应的值 import re exp= '<abc>akd7008&(&*)hgdwuih</abc>008&(&*)hgdwuih</abd>' ret= re.search(r'<(\w+)>.*?</\1>',exp) # r 表示取消在python字符串中所有的转义 在正则表达式中,\1表示第一个分组 ret= re.search('<(\w+)>.*?</\\1>',exp) #\\1 转义 print(ret) ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>") print(ret.group(1)) print(ret.group()) #结果 :<h1>hello</h1> #匹配整数: import re ret=re.findall(r"\d+\.\d+|\d+","1-2*(60+(-40.35/5)-(-4*3))") print(ret)#['1', '2', '60', '40.35', '5', '4', '3'] ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))") #要想得到整数,匹配整数或小数,只显示整数 print(ret)#['1', '2', '60', '', '5', '4', '3'] 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'] #列表去除空元素(假如有多个),但不能改变顺序 l = ['1', '2', '60', '', '5', '4', '3','',''] for i in range(l.count('')): l.remove('') #默认删除从左数第一个 print(l)#['1', '2', '60', '5', '4', '3'] ret = filter(lambda n:n,l) print(list(ret))#['1', '2', '60', '5', '4', '3'] #爬虫练习: import requests import re import json def getpage(url): response = requests.get(url) return response.text def parsepage(s): com = re.compile( '<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>', re.s) ret = com.finditer(s) for i in ret: yield { "id": i.group("id"), "title": i.group("title"), "rating_num": i.group("rating_num"), "comment_num": i.group("comment_num"), } def main(num): url = 'https://movie.douban.com/top250?start=%s&filter=' % num response_html = getpage(url) ret = parsepage(response_html) f = open("move_info7", "a", encoding="utf8") for obj in ret: print(obj) data = json.dumps(obj, ensure_ascii=false) f.write(data + "\n") if __name__ == '__main__': count = 0 for i in range(10): main(count) count += 25
递归的定义——在一个函数里再调用这个函数本身
count = 0 def func(): global count count += 1 print(count) func() print(456) func()#recursionerror: maximum recursion depth exceeded while calling a python object 报错 # recursionerror python中递归的最大深度1000层 : 为了节省内存空间,不要让用户无限使用内存空间 1.递归要尽量控制次数,如果需要很多层递归才能解决问题,不适合用递归解决 2.循环和递归的关系 # 递归不是万能的 # 递归比起循环来说更占用内存 3.修改递归的最大深度 import sys sys.setrecursionlimit(100000)#将python允许的递归深度设置为了10w,至于实际可以达到的深度就取决于计算机的性能了 4.递归函数 必须要停下来: 一个递归函数要想结束,必须在函数内写一个return,并且return的条件必须是一个可达到的条件 并不是函数中有return,return的结果就一定能够在调用函数的外层接收到 # 如何递归4次结束整个函数? count = 0 def func(): global count count += 1 print(count) if count == 4: return func() print(456) func() # 1 # 2 # 3 # 4 # 456 # 456 # 456 def func(count): count += 1 print(count) if count == 5 : return 5 ret = func(count) print(count ,':',ret) return ret print('-->',func(1)) # 2 # 3 # 4 # 5 # 4 : 5 # 3 : 5 # 2 : 5 # --> 5 def func(count): count += 1 print(count) if count == 5 : return 5 return func(count) print('-->',func(1)) # 2 # 3 # 4 # 5 # --> 5 # 练习: # 计算阶乘 100! = 100*99*98*97*96....*1 #用循环 或者 递归 def fin(n): if n ==1 : return n else: return n*fin(n-1) ret = fin(5) print(ret)#120