当前位置: 移动技术网 > IT编程>脚本编程>Python > re模块,递归函数

re模块,递归函数

2019年05月29日  | 移动技术网IT编程  | 我要评论

渣婚之后 19楼,手机数码,盐城旅游网

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



如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网