模块一(re模块)

一、re模块

首先说一下什么是模块,模块就是一组功能的集合。你要和某个东西打交道,而这个东西本身和python没关系,这个东西本身就存在,所以python提供了一个功能的集合专门负责和这个东西打交道。

模块的类型:

内置模块:不需要我们自己安装,解释器自带的;

第三方模块:需要我们自己安装的模块;

自定义模块:我们自己写的模块;

为什么要有模块?先举一个例子:我们都知道是操作系统把所有硬件管理起来的,文件是在硬盘上存储的,python想从硬盘上进行文件的操作和删除时就需要引入os模块,说白了,模块实际上就是给我们提供功能,这个要操作的内容本身就存在,模块只不过是python提供给我们去操作这个内容的方法。

注意:永远不要起一个和你已知的模块同名的py文件的名字!

今天我们就来学习一下re模块的几个基础方法,在python中使用正则表达式就要引入re模块。

1,查找

  findall:表示匹配每一项都是列表中的一个元素。 (重要程度*****)

语法规则:re.findall(‘正则表达式’, 待匹配字符串 , flag),具体示例如下:

    import re
    ret = re.findall(‘\d+‘, ‘sjkhk172按实际花费928‘)
    print(ret)  # 结果为:[‘172‘, ‘928‘]

    ret = re.findall(‘\d‘, ‘sjkhk172按实际花费928‘)
    print(ret)  # 结果为:[‘1‘, ‘7‘, ‘2‘, ‘9‘, ‘2‘, ‘8‘]

  search:只匹配从左到右的第一个,得到的不是直接的结果,而是一个变量,通过这个变量的group方法来获取结果,如果没有匹配到,会返回None,使用group会报错。(重要程度*****)

语法规则:re.search(‘正则表达式’, 待匹配字符串 , flag),具体示例如下:

    ret = re.search(‘\d+‘, ‘sjkhk172按实际花费928‘)
    print(ret)  # 结果为:<_sre.SRE_Match object; span=(5, 8),     match=‘172‘>
    print(ret.group()) # 结果为:172

    ret = re.search(‘\d‘,‘owghabDJLBNdgv‘)
    print(ret)   # 结果为:None
    print(ret.group())   # 会报错

    # 因为search方法查找的时候,若待匹配的字符串中没有能匹配到的结果时,
    # 用group会报错,所以通常我们写成下面这样
    ret = re.search(‘\d+‘,‘sjkhk172按实际花费928‘)
    if ret :   # 内存地址,这是一个正则匹配的结果
        print(ret.group()) # 通过ret.group()获取真正的结果

  match:从头开始匹配,相当于search中的正则表达式加上一个^。(重要程度**)

语法规则:re.match(‘正则表达式’, 待匹配字符串 , flag),具体示例如下:

    ret = re.match(‘\d+$‘,‘sjkhk172按实际花费928‘)
    print(ret)  # 结果为:None
    ret = re.match(‘\d+‘,‘172sjkhk按实际花费928‘)
    print(ret)  # 结果为:<_sre.SRE_Match object; span=(0, 3),     match=‘172‘>
    print(ret.group())  # 结果为:172
    ret = re.match(‘\d+$‘,‘172sjkhk按实际花费928‘)
    print(ret)  # 结果为:None

2,字符串处理的扩展

切割:re.split(‘正则表达式’, 待匹配字符串),用正则表达式匹配出来的结果对待匹配字符串切割。如下:

    s = ‘alex83taibai40egon25‘
    ret = re.split(‘\d+‘,s)
    print(ret)  # 结果为:[‘alex‘, ‘taibai‘, ‘egon‘, ‘‘]

  替换:sub和subn

re.sub(‘正则表达式’, ‘新内容’, 待匹配字符串 , 替换次数)

    re.subn(‘正则表达式’, ‘新内容’, 待匹配字符串 , 替换次数) ,示例如下:

    ret = re.sub(‘\d+‘,‘H‘,‘alex83taibai40egon25‘)
    print(ret)  # 结果为:alexHtaibaiHegonH
    ret = re.sub(‘\d+‘,‘H‘,‘alex83taibai40egon25‘,1)
    print(ret)  # 结果为:alexHtaibai40egon25

    ret = re.subn(‘\d+‘,‘H‘,‘alex83taibai40egon25‘)
    print(ret)  # 结果为:(‘alexHtaibaiHegonH‘, 3)
    ret = re.subn(‘\d+‘,‘H‘,‘alex83taibai40egon25‘, 2)
    print(ret)  # 结果为:(‘alexHtaibaiHegonH‘, 2)
    # 我们可以看出sub和subn的区别是subn返回一个元组,元组第二个元素是替换次数。

3,re模块的进阶:时间和空间上更优化

compile:节省使用正则表达式解决问题的时间(编译,就是将正则表达式编译成字节码,这样在多次使用的过程中不会多次编译,可以用这个结果去直接search、match、findall、finditer),具体示例如下:

    ret = re.compile(‘\d+‘)   # 编译
    print(ret)  # 结果为:re.compile(‘\\d+‘)
    res = ret.findall(‘alex83taibai40egon25‘)  # 编译后直接使用
    print(res)
    res = ret.search(‘sjkhk172按实际花费928‘)  # 编译后直接使用
    print(res.group())

  finditer:节省使用正则表达式解决问题的空间/内存(返回一个迭代器,所有的结果都在这个迭代器中,可以通过循环和group取出来),具体示例如下:

    ret = re.finditer(‘\d+‘,‘alex83taibai40egon25‘)
    print(ret)  # 结果为:<callable_iterator object at 0x00000000029EFDA0>
    for i in ret:
        print(i.group())
    # 结果为:
    # 83
    # 40
    # 25

二、在python中使用正则表达式的特点和问题

1,分组在re模块中的使用,分析如下几段代码,理解并总结规则:

    # 1 search方法中对正则分组,通过group(n)取出相应内容
    s = ‘<a>wahaha</a>‘
    ret = re.search(‘<(\w+)>(\w+)</(\w+)>‘,s)
    print(ret.group())  # 结果为:<a>wahaha</a>,默认取出所有匹配内容
    print(ret.group(1)) # 数字参数代表的是取对应分组中的内容,结果为:a
    print(ret.group(2))  # 结果为:wahaha
    print(ret.group(3))  # 结果为:a

    # 2 findall也可以顺利取到分组中的内容,因为它有一个特殊的语法,就是优先显示分组中的内容
    ret = re.findall(‘(\w+)‘,s)
    print(ret)  # 结果为:[‘a‘, ‘wahaha‘, ‘a‘]
    ret = re.findall(‘>(\w+)<‘,s)
    print(ret)  # 结果为:[‘wahaha‘]

    # 3 取消分组优先(?:正则表达式)
    ret = re.findall(‘>(?:\w+)<‘,s)
    print(ret)  # 结果为:[‘>wahaha<‘]
    ret = re.findall(‘\d+(?:\.\d+)?‘,‘1.234*4‘)
    print(ret)   # 结果为:[‘1.234‘, ‘4‘]
    # 当你想用()表示正则里的分组,而不想表示优先显示的时候可以用?:取消分组

  综上: 对于正则表达式来说,有些时候我们需要进行分组,来整体约束某一组字符出现的次数;对于python语言来说,分组可以帮助你更好更精准的找到你真正需要的内容;具体想表示哪种分组,要看情况决定。

    # 4 split方法中可以对正则加括号表示使切割的字符不丢失
    ret = re.split(‘\d+‘,‘alex83taibai40egon25‘)
    print(ret)  # 结果为:[‘alex‘, ‘taibai‘, ‘egon‘, ‘‘]
    ret = re.split(‘(\d+)‘,‘alex83taibai40egon25‘)
    print(ret)  # 结果为:[‘alex‘, ‘83‘, ‘taibai‘, ‘40‘, ‘egon‘, ‘25‘, ‘‘]

    # 分组命名 (?P<组名>正则表达式)
    s = ‘<a>wahaha</a>‘
    ret = re.search(‘>(?P<con>\w+)<‘,s)
    print(ret.group(1))  # 结果为:wahaha
    print(ret.group(‘con‘))  # 结果为:wahaha

    # 使用前面的分组 要求使用这个名字的分组和前面同名分组中的内容匹配的必须一致
    pattern = ‘<(?P<tab>\w+)>(\w+)</(?P=tab)>‘
    ret = re.search(pattern,s)
    print(ret.group())   # 结果为:<a>wahaha</a>
    # 可以练习下列的匹配:
    # 2018-12-06
    # 2018.12.6
    # 2018 12 06
    # 12:30:30

三、使用正则表达式的技巧

当你要匹配的内容太没有特点,容易和你不想匹配的内容混在一起的时候,就可以把不想匹配的也取出来,然后通过python过滤掉,具体示例如下:

    # 想只取整数,但是会带上小数,那么把整数和小数都取出来,然后再过滤掉小数
    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))")
    ret.remove(‘‘)
    print(ret)  # 结果为:[‘1‘, ‘2‘, ‘60‘, ‘5‘, ‘4‘, ‘3‘]

四、爬虫的例子

预备知识:如何获取一个页面的源代码,如下可以做到:

    from urllib import request
    ret = request.urlopen(‘https://movie.douban.com/top250?    start=50&filter=‘)
    res = ret.read().decode(‘utf-8‘)
    print(res)

  分析并掌握如下爬虫的小例子:

    import re
    from urllib.request import urlopen

    def getPage(url):   # 获取网页的字符串
        response = urlopen(url)
        return response.read().decode(‘utf-8‘)

    def parsePage(s):
        ret = com.finditer(s)  # 从s这个网页源码中 找到所有符合com正则表达式规则的内容 并且以迭代器的形式返回
        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):  # 0  25 50  # 这个函数执行10次,每次爬取一页的内容
        url = ‘https://movie.douban.com/top250?start=%s&filter=‘ % num
        response_html = getPage(url)   # response_html就是这个url对应的html代码 就是 str
        ret = parsePage(response_html) # ret是一个生成器
        print(ret)
        f = open("move_info7", "a", encoding="utf8")
        for obj in ret:
            print(obj)
            data = str(obj)
            f.write(data + "\n")
        f.close()

    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)

    count = 0
    for i in range(10):
        main(count)
        count += 25

写在最后:

  正则表达式到底重要到什么程度?

  掌握作业中的所有内容

  能够看懂常用的正则表达式

  并且能够做出一些公司特异性要求的修改

原文地址:https://www.cnblogs.com/li-li/p/9494832.html

时间: 2024-11-09 03:46:17

模块一(re模块)的相关文章

day5模块学习 -- os模块学习

python基础之模块之os模块 os模块 os模块的作用: os,语义为操作系统,所以肯定就是操作系统相关的功能了,可以处理文件和目录这些我们日常手动需要做的操作,就比如说:显示当前目录下所有文件/删除某个文件/获取文件大小-- 另外,os模块不受平台限制,也就是说:当我们要在linux中显示当前命令时就要用到pwd命令,而Windows中cmd命令行下就要用到这个,额...我擦,我还真不知道,(甭管怎么着,肯定不是pwd),这时候我们使用python中os模块的os.path.abspath

python下通过os模块和shutil模块进行文件处理方式

python下通过os模块和shutil模块进行文件处理方式 得到当前工作目录路径:os.getcwd() 获取指定目录下的所有文件和目录名:os.listdir(dir) 删除文件:os.remove(file) 删除多个目录:os.removedirs(r"/home") 检测路径是否为文件:os.path.isfile(path) 检测路径是否为目录:os.path.isdir(path) 判断是否为绝对路径:os.path.isabs(path) 检测路径是否存在:os.pat

Python基础(12)_python模块之sys模块、logging模块、序列化json模块、pickle模块、shelve模块

5.sys模块 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称 5.1 使用sys.argv进行登录判断,跳过 i/o阻塞 #使用sys.argv进行登录判断,跳过 i/o阻塞 import s

python基础知识8——模块1——自定义模块和第三方开源模块

模块的认识 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块. 如:os 是系统相关的模块:file是文件操作相关的模块 模块分为三种: 自定义模块 内置模块 第三方开源模块 自定义模块 1.定义模块 2.导入模块 Python之所以应用越来越广泛,在一定程度上也

模块之使用模块

你已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个包含了所有你定义的函数和变量的文件.为了在其他程序中重用模块,模块的文件名必须以.py为扩展名.模块可以从其他程序 输入 以便利用它的功能.这也是我们使用Python标准库的方法.首先,我们将学习如何使用标准库模块.使用sys模块~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 例8.1 使用sys模块 #!/usr

Python模块 实现过渡性模块重载

本文是在阅读Python 学习手册后  感觉比较不错的一个实现模块重载的一个模块,该模块可以实现对已经加载在运行程序中的模块实现重新加载,并且该模块可以递归的实现对要重新加载的模块内所引用的其它模块的重新加载. """ reloadall.py: transitively reload nested modules """ import types from imp import reload def status(module): print

pickle模块和json模块

不要把文件命名为模块名 #pickle模块 序列化 import pickle dic = {'name':'dodo','age':18} print(pickle.dumps(dic))#转成了bytes类型 with open('a.pickle','wb')as f:#存 f.write(pickle.dumps(dic)) #简单方法 pickle.dump(dic,open('b.pickle','wb')) 反序列化 with open('a.pickle','rb')as f:#

python第十七天---时间模块、random模块

作完一个作业,开始新的学习: 有由今天的时间有限所有学习了以下两个模块,明天继续! 时间模块.random模块 import time 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import time ,datetime 5 print(time.process_time())#测量处理器运算时间,不包括sleep时间 6 7 print(time.altzone)#返回与UTC时间的时间差 以秒计算 8

requireJS的匿名模块和命名模块的区别和最佳实践

requirejs是一个简单的javascript框架,支持模块化编码和模块的异步载入. 在requireJS中模块能够分为:匿名模块和命名模块这2种. requireJS定义一个匿名模块 define(function(){ return {id:"noName"}; }); requireJS定义一个命名模块 define("constantModule",[],function(){ return {id:"hasName"}; }); r

Python的StringIO模块和cStringIO模块

1.StringIO模块 StringIO用于像文件一样对字符串缓冲区或者叫做内存文件进行读写. f = StringIO()      # ready for writing f = StringIO(buf)   # ready for reading f.close()           # explicitly release resources held flag = f.isatty()   # always false pos = f.tell()      # get curr