python全栈开发【第九篇】Python常用模块一(主要是re正则和collections)

一、认识模块

    什么是模块:一个模块就是一个包含了python定义和声明的文件,文件名就是加上.py的后缀,但其实import加载的模块分为四个通用类别 :

    1.使用python编写的代码(.py文件)

    2.已被编译为共享库二和DLL的C或C++扩展

    3.包好一组模块的包

    4.使用C编写并连接到python解释器的内置模块

    为何要使用莫模块?

    如果你想退出python解释器然后重新进入,那么你之前定义的函数或变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时,就通过python test.py 方式去执行,此时test.py被称为脚本script。

    随着程序的发展,功能越来越多,为了方便管理,我们通常将文件分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以吧这些文件当做脚本去执行,还可以把它们当做模块来导入到其他模块中,实现了功能的重复利用。

二、常见模块分类

  常用模块一、

      collocations 模块

      时间模块

      random模块

      os模块

      sys模块

      序列化模块

      re模块

  常用模块二:这些模块和面向对象有关

      hashlib模块

      configparse模块

      logging模块

三、正则表达式

像我们平常见的那些注册页面啥的,都需要我们输入手机号码吧,你想我们的电话号码也是有限定的吧(手机号码一共11位,并且只以13,14,15,17,18开头的数字这些特点)如果你的输入有误就会提示,那么实现这个程序的话你觉得用While循环so easy嘛,那么我们来看看实现的结果。

#判断手机号码是否合法
while True:
    phone_number=input(‘请输入你的电话号码:‘)
    if len(phone_number)==11 and phone_number.isdigit()        and (phone_number.startswith(‘13‘)        or phone_number.startswith(‘14‘)         or phone_number.startswith(‘15‘)         or phone_number.startswith(‘17‘)         or phone_number.startswith(‘18‘)):
        print(‘是合法的手机号码‘)
    else:
        print(‘不是合法的手机号码‘)

看到这个代码,虽说理解很容易,但是我还有更简单的方法。那我们一起来看看吧。

import re
phone_number=input(‘请输入你的电话号码:‘)
if re.match(‘^(13|14|15|17|18)[0-9]{9}$‘,phone_number):
    ‘‘‘^这个符号表示的是判断是不是以13|14|15|17|18开头的,
    [0-9]: []表示一个字符组,可以表示0-9的任意字符
    {9}:表示后面的数字重复九次
    $:表示结束符
    ‘‘‘
    print(‘是合法的手机号码‘)
else:
    print(‘不是合法的手机号码‘)

那么什么是正则呢?

  首先你要知道的是,谈到正则,就只和字符串相关了。在线测试工具 http://tool.chinaz.com/regex/

比如你要用‘1’去匹配‘1’,或者用‘2’去匹配‘2’,直接就可以匹配上。

字符组:[字符组]
在同一位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
字符分为很多类,比如数字,字母,标点等登。
假如你现在要求一个位置‘只能出现一个数字’,那么这个位置上的字符只能是0、1、2、3.......9这是个数之一。

字符组:

字符:

量词:

.^$

*+?{}

注意:前面的*,+,?等都是贪婪匹配,也就是尽可能多的匹配,后面加?就变成了非贪婪匹配,也就是惰性匹配。

贪婪匹配:

几个常用的配贪婪匹配

*?;重复任意次,但尽可能少重复

+?:重复一次或更多次,但尽可能少重复

??:重复0次或1次,但尽可能少重复

{n,m}:重复n到m次,但尽可能少重复

{n,}: 重复n次以上,但尽可能少重复

.*?的用法:

.是任意字符
*是取0到无限长度
?是非贪婪模式
和在一起就是取尽量少的任意字符,一般不会这么单独写,大多用在:
.*?x
意思就是取前面任意长度的字符,直到一个x出现

字符集:

分组()与或|[^]:

1)^[1-9]\d{13,16}[0-9x]$     #^以数字0-9开始,

                                \d{13,16}重复13次到16

                                $结束标志

上面的表达式可以匹配一个正确的身份证号码

2)^[1-9]\d{14}(\d{2}[0-9x])?$     

#?重复0次或者1次,当是0次的时候是15位,是1的时候是18位

3)^([1-9]\d{16}[0-9x]|[1-9]\d{14})$

#表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}          

  

#对于分组的理解
举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的。因此,如果想获取页面标题(xxx),充其量只能写一个类似于这样的表达式:<title>.*</title>,而这样写匹配出来的是完整的<title>xxx</title>标签,并不是单纯的页面标题xxx。

       想解决以上问题,就要用到断言知识。

       在讲断言之前,读者应该先了解分组,这有助于理解断言。

       分组在正则中用()表示,根据小菜理解,分组的作用有两个:

       n  将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。

       n  分组之后,可以通过后向引用简化表达式。

       先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:

       \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}

       但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:

       \d{1,3}(.\d{1,3}){3}

       这样一看,就比较简洁了。

再来看第二个作用,就拿匹配<title>xxx</title>标签来说,简单的正则可以这样写:

       <title>.*</title>

       可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:

       <(title)>.*</\1>

       这个例子实际上就是反向引用的实际应用。对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。

       用\1这种语法,可以引用某组的文本内容,\1当然就是引用第1组的文本内容了,这样一来,就可以简化正则表达式,只写一次title,把它放在组里,然后在后边引用即可。

       以此为启发,我们可不可以简化刚刚的IP地址正则表达式呢?原来的表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下:

       (\d{1,3})(.\1){3}

       简单的解释下,把\d{1,3}放在一组里,表示为(\d{1,3}),它是第1组,(.\1)是第2组,在第2组里通过\1语法,后向引用了第1组的文本内容。

       经过实际测试,会发现这样写是错误的,为什么呢?

       小菜一直在强调,后向引用,引用的仅仅是文本内容,而不是正则表达式!

       也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。

       因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。

分组命名:语法(?p<name>)注意先命名,后正则

import  re
import re
ret=re.search(‘<(\w+)>\w+<(/\w+)>‘,‘<h1>hello</h1>‘)
print(ret.group())
# 给分组起个名字。就用下面的分组命名,上面的方法和下面的分组命名是一样的,只不过就是给命了个名字
ret=re.search(‘<(?P<tag_name>\w+)>\w+</(?P=tag_name)>‘,‘<h1>hello</h1>‘)

#(?P=tag_name)就代表的是(\w+)
print(ret.group()) # 了解(和上面的是一样的,是上面方式的那种简写)
ret=re.search(r‘<(\w+)>\w+</\1>‘,‘<h1>hello</h1>‘)
print(ret.group(1))

转义符:

四、re模块

re模块相关的方法  

# 1.re模块下的常用方法
# 1.findall方法
import re
ret = re.findall(‘a‘,‘eva ang  egons‘)
# #返回所有满足匹配条件的结果,放在列表里
print(ret)

# 2.search方法
# 函数会在字符串中查找模式匹配,只会找到第一个匹配然后返回
# 一个包含匹配信息的对象,该对象通过调用group()方法得到匹配的
# 字符串,如果字符串没有匹配,则报错
ret = re.search(‘s‘,‘eva ang  egons‘)#找第一个
print(ret.group())

# 3.match方法
print(re.match(‘a‘,‘abc‘).group())
#同search,只从字符串开始匹配,并且guoup才能找到

# 4.split方法
print(re.split(‘[ab]‘,‘abcd‘))
#先按‘a‘分割得到‘‘和‘bcd‘,在对‘‘和‘bcd‘分别按‘b‘分割

# 5.sub方法
print(re.sub(‘\d‘,‘H‘,‘eva3sdf4ahi4asd45‘,1))
# 将数字替换成‘H‘,参数1表示只替换一个

# 6.subn方法
print(re.subn(‘\d‘,‘H‘,‘eva3sdf4ahi4asd45‘))
#将数字替换成’H‘,返回元组(替换的结果,替换了多少次)

# 7.compile方法
obj = re.compile(‘\d{3}‘)#将正则表达式编译成一个正则表达式对象,规则要匹配的是三个数字
print(obj)
ret = obj.search(‘abc12345eeeee‘)#正则表达式对象调用search,参数为待匹配的字符串
print(ret.group()) #.group一下就显示出结果了

# 8.finditer方法
ret = re.finditer(‘\d‘,‘dsf546sfsc‘)#finditer返回的是一个存放匹配结果的迭代器
# print(ret)#<callable_iterator object at 0x00000000021E9E80>
print(next(ret).group())#查看第一个结果
print(next(ret).group())#查看第二个结果
print([i.group() for i in ret] )#查看剩余的左右结果

findall的优先级查询

import re
ret = re.findall(‘www.(baidu|oldboy).com‘,‘www.oldboy.com‘)
print(ret)   #结果是[‘oldboy‘]这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

ret = re.findall(‘www.(?:baidu|oldboy).com‘,‘www.oldboy.com‘)
print(ret) #[‘www.oldboy.com‘]

split的优先级查询

ret = re.split(‘\d+‘,‘eva123dasda9dg‘)#按数字分割开了
print(ret) #输出结果:[‘eva‘, ‘dasda‘, ‘dg‘]

ret = re.split(‘(\d+)‘,‘eva123dasda9dg‘)
print(ret) #输出结果:[‘eva‘, ‘123‘, ‘dasda‘, ‘9‘, ‘dg‘]
#
# 在匹配部分加上()之后和不加括号切出的结果是不同的,
# 没有括号的没有保留所匹配的项,但是有括号的却能够保留了
# 匹配的项,这个在某些需要保留匹配部分的使用过程是非常重要的

五、re模块和正则表达式的关系

re模块和正则表达式没有一点毛线关系。re模块和正则表达式的关系类似于time模块和时间的关系,你没有学习python之前,也不知道有一个time模块,但是你已经认识时间了呀,12:30就表示中午十二点半。时间有自己的格式,年月日时分秒,已成为一种规则。你早就牢记于心了,time模块只不过是python提供给我们的可以方便我们操作时间的一个工具而已。

六、collections模块

在内置数据类型(dict,list,set,tuple)的基础上,collections 模块还提供了几个额外的数据类型:

1.namedtuple:生成可以使用名字来访问元素内容的tuple

2.deque:双向队列(两头都可进可出,但是不能取中间的值),可以快速的从另外一侧追加和推出对象

3.Counter:计数器,主要用来计数

4.OrderedDict:有序字典

5.defaultdict:带有默认值的字典

namedtuple:

  我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:p=(1,2)

但是,看到(1,2),很难看出这个tuple是用来表示坐标的。

那么,我们的namedtuple就能用上了。

namedtuple(‘名称‘,‘属性list’)

from  collections import namedtuple
point = namedtuple(‘point‘,[‘x‘,‘y‘])
p = point(1,2)
print(p.x,p.y)、<br><br><br>
Circle = namedtuple(‘Circle‘, [‘x‘, ‘y‘, ‘r‘])#用坐标和半径表示一个圆

deque 

单向队列<br># import queue  #队列模块

# q = queue.Queue()

# q.put(10)

# q.put(20)

# q.put(30)

# # 10 20 30

# print(q.get())

# print(q.get())

# print(q.get())

# print(q.get())

deque是为了高效实现插入和删除操作的双向队列,适用于队列和栈

from collections import deque
q = deque([‘a‘,‘b‘,‘c‘])
q.append(‘ee‘)#添加元素
q.append(‘ff‘)
q.append(‘qq‘)
print(q)
q.appendleft(‘www‘)#从左边添加
print(q)

q.pop() #删除元素
q.popleft() #从左边删除元素
print(q)

OrderedDict

使用字典时,key是无序的。在对字典做迭代时,我们无法确定key的顺序。如果要保持key的顺序,可以用OrderedDict 

from collections import OrderedDict

  

d = {‘z‘:‘qww‘,‘x‘:‘asd‘,‘y‘:‘asd‘,‘name‘:‘alex‘}print(d.keys()) #key是无序的

od = OrderedDict([(‘a‘1), (‘b‘2), (‘c‘3)]) print(od)# OrderedDict的Key是有序的 <br>OrderedDict([(‘a‘, 1), (‘b‘, 2), (‘c‘, 3)])<br><br><br>

注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

od = OderedDict ()

od[‘z‘]=1

od[‘y‘]=2

od[‘x‘]=3

print(od.keys())   #按照插入额key的顺序返回

defaultdict  

#找大于66和小于66的
d = {‘z‘:‘qww‘,‘x‘:‘asd‘,‘y‘:‘asd‘,‘name‘:‘alex‘}
print(d.keys())
from  collections import defaultdict
values = [11,22,33,44,55,66,77,88,99]
my_dict = defaultdict(list)
for v in values:
    if v>66:
        my_dict[‘k1‘].append(v)
    else:
        my_dict[‘k2‘].append(v)
print(my_dict)
from collections import defaultdict
dd = defaultdict(lambda: ‘N/A‘)
dd[‘key1‘] = ‘abc‘
print(dd[‘key1‘]) # key1存在

print(dd[‘key2‘]) # key2不存在,返回默认值

 

Counter

Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

from collections import Counter
c = Counter(‘abcdeabcdabcaba‘)
print(c)
# 输出:Counter({‘a‘: 5, ‘b‘: 4, ‘c‘: 3, ‘d‘: 2, ‘e‘: 1})
其他详细内容 http://www.cnblogs.com/Eva-J/articles/7291842.html

  

  

 

  

原文地址:https://www.cnblogs.com/xiaohema/p/8453264.html

时间: 2024-10-10 02:38:57

python全栈开发【第九篇】Python常用模块一(主要是re正则和collections)的相关文章

Python全栈开发:初识Python

Pythton简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承. Python(英国发音:/?pa?θ?n/ 美国发音:/?pa?θɑ?n/),是一种面向对象.直译式的计算机程序语言,具有近二十年的发展历史.它包含了一组功能完备的标准库,能够轻松完成很多常见的任务.它的语法简单,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块. 与

Python 全栈开发【第一篇】:目录

Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基础语法入门 Python 全栈开发[第三篇]:数据类型.字符编码.文件操作 第二阶段:函数编程&常用标准库 Python 全栈开发[第四篇]:函数.递归.生成器.迭代器 Pyhton 全栈开发[第五篇]:常用模块学习 第三阶段:面向对象编程&网络编程基础 Python 全栈开发[第六篇]:面向对象

Python全栈开发【第一篇】:初识Python

Python全栈开发[第一篇] 本节内容: Python 的种类 Python 的环境 Python 入门(解释器.编码.变量.input输入.if流程控制与缩进.while循环) if流程控制与while循环练习题 基本数据类型前引 Python 的种类 Cpython Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚拟机上. Jyhton Python的Java实现,Jython会将Pyth

Python全栈开发记录_第一篇

Python全栈开发记录只为记录全栈开发学习过程中一些难和重要的知识点,还有问题及课后题目,以供自己和他人共同查看.(代码行数:70行) 知识点1:优先级:not>and 短路原则:and:如果第一个条件的结论为假,那么 and 前后两个条件组成的表达式计算结果一定为假,后面的条件计算机不会进行计算 or:如果第一个条件的结论为真,那么or 前后两个条件组成的表达式计算结果一定为真,后面的条件计算机不会进行计算 知识点2:python区分大小写,常量需全部字母大写(默认这样写) python换行

python全栈开发-Day8 函数基础

python全栈开发-Day8 函数 一 .引子 1. 为何要用函数之不用函数的问题 #1.代码的组织结构不清晰,可读性差 #2.遇到重复的功能只能重复编写实现代码,代码冗余 #3.功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大  2. 函数是什么? 针对二中的问题,想象生活中的例子,修理工需要实现准备好工具箱里面放好锤子,扳手,钳子等工具,然后遇到锤钉子的场景,拿来锤子用就可以,而无需临时再制造一把锤子. 修理工===>程序员 具备某一功能的工具===>函数

Python全栈开发

Python全栈开发 一文让你彻底明白Python装饰器原理,从此面试工作再也不怕了. 一.装饰器 装饰器可以使函数执行前和执行后分别执行其他的附加功能,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),装饰器的功能非常强大,但是理解起来有些困难,因此我尽量用最简单的例子一步步的说明这个原理. 1.不带参数的装饰器 假设我定义了一个函数f,想要在不改变原来函数定义的情况下,在函数运行前打印出start,函数运行后打印出end,要实现这样一个功能该怎么实现?看下面如何用

python全栈开发目录

python全栈开发目录 linux命令 初识python python基础数据类型 函数编程.set.深浅拷贝 内置函数 文件操作 装饰器 迭代器和生成器 常用模块 初识类和对象 类和对象(进阶) 反射 异常处理 socket.IO多路复用 线程.进程.协程 HTML CSS JavaScript DOM文档操作 jQuery实例 web框架本质 Tornado mysql基础 mysql进阶 ..... 基本算法 递归--二分法查找 冒泡排序 更多 线程池

Python 全栈开发:python列表List

列表 列表是python中经常使用的数据类型,用于存放多个值. 表现形式:在[ ]内用逗号分隔,可以存放n个任意类型的值 eg: #单一类型 users=['yangli','yite','fixd'] #多类型,列表嵌套 users=['room01',['yangli',20,'音乐'],['yite',20,'篮球'],] 列表常用方法 和 函数 方法 函数 常用的操作 eg: len(list) #len(list) 计算列表的长度 ls = ['a','b','c','d'] leng

Python 全栈开发:python元组tuple

元组 什么是元组:"元组就是一个不可变的列表" (并不是列表,只是为了便于记忆) 用途:用于存放多个值,只能读不能二次赋值 表现形式:小括号()中间以逗号分割各个元素 eg: tuples = ('a','b','c','d') 元组常用的操作 生成一个简单的元组 tuples = tuple(range(5)) print(tuples) #结果(0, 1, 2, 3, 4) len(tuple) #计算元组长度 tuples = (0, 1, 2, 3, 4) print(len(

python全栈开发学习目录

python全栈开发学习目录 第一章 计算机基础 第二章Python入门 第三章数据类型 第四章文件操作 第五章函数 第六章 模块 第七章 面向对象 第八章 网络编程 第九章 并发编程 第十章 数据库 第十一章 前端开发-html 第十一章 前端开发-css 附加:js特效 15个小demo 第十一章 前端开发-JavaScript 第十一章 前端开发-jQuery 第十一章 前端开发-bootstrap 第十二章 Django框架开发 ... 原文地址:https://www.cnblogs.