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

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






re模块,递归函数

递归的定义——在一个函数里再调用这个函数本身
        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