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嘛,那么我们来看看实现的结果。
1 while True:
2 phone_number=input('请输入你的电话号码:')
3 if len(phone_number)==11 and phone_number.isdigit()\
4 and (phone_number.startswith('')\
5 or phone_number.startswith('') \
6 or phone_number.startswith('') \
7 or phone_number.startswith('') \
8 or phone_number.startswith('')):
9 print('是合法的手机号码')
10 else:
11 print('不是合法的手机号码')
判断手机号码是否合法
看到这个代码,虽说理解很容易,但是我还有更简单的方法。那我们一起来看看吧。
1 import re
2 phone_number=input('请输入你的电话号码:')
3 if re.match('^(13|14|15|17|18)[0-9]{9}$',phone_number):
4 '''^这个符号表示的是判断是不是以13|14|15|17|18开头的,
5 [0-9]: []表示一个字符组,可以表示0-9的任意字符
6 {9}:表示后面的数字重复九次
7 $:表示结束符
8 '''
9 print('是合法的手机号码')
10 else:
11 print('不是合法的手机号码')
判断手机号码输入是否合法
大家可能都觉的第一种方法更简单吧,但是如果我让你从整个文件中匹配出所有的手机号码,你能用python写出来吗?但是导入re模块和利用正则表达式就可以解决这一个问题了。
那么什么是正则呢?
首先你要知道的是,谈到正则,就只和字符串相关了。在线测试工具 http://tool.chinaz.com/regex/
比如你要用‘1’去匹配‘1’,或者用‘2’去匹配‘2’,直接就可以匹配上。
字符组:[字符组]
在同一位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
字符分为很多类,比如数字,字母,标点等登。
假如你现在要求一个位置‘只能出现一个数字’,那么这个位置上的字符只能是0、1、2、3.......9这是个数之一。
字符组:
字符:
量词:
.^$
*+?{}
注意:前面的*,+,?等都是贪婪匹配,也就是尽可能多的匹配,后面加?就变成了非贪婪匹配,也就是惰性匹配。
贪婪匹配:
几个常用的配贪婪匹配
1
2
3
4
5
|
* ?;重复任意次,但尽可能少重复 + ?:重复一次或更多次,但尽可能少重复 ??:重复 0 次或 1 次,但尽可能少重复 {n,m}:重复n到m次,但尽可能少重复 {n,}: 重复n次以上,但尽可能少重复 |
.*?的用法:
1
2
3
4
5
6
|
.是任意字符 * 是取 0 到无限长度 ?是非贪婪模式 和在一起就是取尽量少的任意字符,一般不会这么单独写,大多用在: . * ?x 意思就是取前面任意长度的字符,直到一个x出现 |
字符集:
分组()与或|[^]:
1
2
3
4
5
6
7
8
9
10
|
( 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} |
1 举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的。因此,如果想获取页面标题(xxx),充其量只能写一个类似于这样的表达式:<title>.*</title>,而这样写匹配出来的是完整的<title>xxx</title>标签,并不是单纯的页面标题xxx。
2
3 想解决以上问题,就要用到断言知识。
4
5 在讲断言之前,读者应该先了解分组,这有助于理解断言。
6
7 分组在正则中用()表示,根据小菜理解,分组的作用有两个:
8
9
10
11 n 将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。
12
13 n 分组之后,可以通过后向引用简化表达式。
14
15
16
17
18
19 先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:
20
21 \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
22
23 但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:
24
25 \d{1,3}(.\d{1,3}){3}
26
27 这样一看,就比较简洁了。
28
29
30
31 再来看第二个作用,就拿匹配<title>xxx</title>标签来说,简单的正则可以这样写:
32
33 <title>.*</title>
34
35 可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:
36
37 <(title)>.*</\1>
38
39 这个例子实际上就是反向引用的实际应用。对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。
40
41 用\1这种语法,可以引用某组的文本内容,\1当然就是引用第1组的文本内容了,这样一来,就可以简化正则表达式,只写一次title,把它放在组里,然后在后边引用即可。
42
43 以此为启发,我们可不可以简化刚刚的IP地址正则表达式呢?原来的表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下:
44
45 (\d{1,3})(.\1){3}
46
47 简单的解释下,把\d{1,3}放在一组里,表示为(\d{1,3}),它是第1组,(.\1)是第2组,在第2组里通过\1语法,后向引用了第1组的文本内容。
48
49 经过实际测试,会发现这样写是错误的,为什么呢?
50
51 小菜一直在强调,后向引用,引用的仅仅是文本内容,而不是正则表达式!
52
53 也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。
54
55 因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。
56
57
58
59 至此,读者已经掌握了传说中的后向引用,就这么简单。
对于分组的理解
分组命名:语法(?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模块
1 # 1.re模块下的常用方法
2 # 1.findall方法
3 import re
4 ret = re.findall('a','eva ang egons')
5 # #返回所有满足匹配条件的结果,放在列表里
6 print(ret)
7
8 # 2.search方法
9 # 函数会在字符串中查找模式匹配,只会找到第一个匹配然后返回
10 # 一个包含匹配信息的对象,该对象通过调用group()方法得到匹配的
11 # 字符串,如果字符串没有匹配,则报错
12 ret = re.search('s','eva ang egons')#找第一个
13 print(ret.group())
14
15
16 # 3.match方法
17 print(re.match('a','abc').group())
18 #同search,只从字符串开始匹配,并且guoup才能找到
19
20
21 # 4.split方法
22 print(re.split('[ab]','abcd'))
23 #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
24
25
26 # 5.sub方法
27 print(re.sub('\d','H','eva3sdf4ahi4asd45',1))
28 # 将数字替换成'H',参数1表示只替换一个
29
30
31 # 6.subn方法
32 print(re.subn('\d','H','eva3sdf4ahi4asd45'))
33 #将数字替换成’H‘,返回元组(替换的结果,替换了多少次)
34
35
36 # 7.compile方法
37 obj = re.compile('\d{3}')#将正则表达式编译成一个正则表达式对象,规则要匹配的是三个数字
38 print(obj)
39 ret = obj.search('abc12345eeeee')#正则表达式对象调用search,参数为待匹配的字符串
40 print(ret.group()) #.group一下就显示出结果了
41
42 # 8.finditer方法
43 ret = re.finditer('\d','dsf546sfsc')#finditer返回的是一个存放匹配结果的迭代器
44 # print(ret)#<callable_iterator object at 0x00000000021E9E80>
45 print(next(ret).group())#查看第一个结果
46 print(next(ret).group())#查看第二个结果
47 print([i.group() for i in ret] )#查看剩余的左右结果
re模块相关的方法
1 import re
2 ret = re.findall('www.(baidu|oldboy).com','www.oldboy.com')
3 print(ret) #结果是['oldboy']这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
4
5 ret = re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
6 print(ret) #['www.oldboy.com']
findall的优先级查询
1 ret = re.split('\d+','eva123dasda9dg')#按数字分割开了
2 print(ret) #输出结果:['eva', 'dasda', 'dg']
3
4 ret = re.split('(\d+)','eva123dasda9dg')
5 print(ret) #输出结果:['eva', '123', 'dasda', '9', 'dg']
6 #
7 # 在匹配部分加上()之后和不加括号切出的结果是不同的,
8 # 没有括号的没有保留所匹配的项,但是有括号的却能够保留了
9 # 匹配的项,这个在某些需要保留匹配部分的使用过程是非常重要的
split的优先级查询
五、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’)
1
2
3
4
|
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
1
2
3
4
5
6
7
8
9
10
|
单向队列<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是为了高效实现插入和删除操作的双向队列,适用于队列和栈
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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
1
|
from collections import OrderedDict |
d = {'z':'qww','x':'asd','y':'asd','name':'alex'}
print(d.keys()) #key是无序的
1
|
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
1 d = {'z':'qww','x':'asd','y':'asd','name':'alex'}
2 print(d.keys())
3 from collections import defaultdict
4 values = [11,22,33,44,55,66,77,88,99]
5 my_dict = defaultdict(list)
6 for v in values:
7 if v>66:
8 my_dict['k1'].append(v)
9 else:
10 my_dict['k2'].append(v)
11 print(my_dict)
找大于66和小于66的
1 from collections import defaultdict
2 dd = defaultdict(lambda: 'N/A')
3 dd['key1'] = 'abc'
4 print(dd['key1']) # key1存在
5
6 print(dd['key2']) # key2不存在,返回默认值
defaultdict
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})
Python之常用模块一(主要RE和collections)的更多相关文章
- python的常用模块之collections模块
python的常用模块之collections模块 python全栈开发,模块,collections 认识模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文 ...
- python常用模块(1):collections模块和re模块(正则表达式详解)
从今天开始我们就要开始学习python的模块,今天先介绍两个常用模块collections和re模块.还有非常重要的正则表达式,今天学习的正则表达式需要记忆的东西非常多,希望大家可以认真记忆.按常理来 ...
- python之常用模块
python 常用模块 之 (subprocess模块.logging模块.re模块) python 常用模块 之 (序列化模块.XML模块.configparse模块.hashlib模块) pyth ...
- python之常用模块二(hashlib logging configparser)
摘要:hashlib ***** logging ***** configparser * 一.hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 摘要算法 ...
- Python学习——python的常用模块
模块:用一堆代码实现了某个功能的代码集合,模块是不带 .py 扩展的另外一个 Python 文件的文件名. 一.time & datetime模块 import time import dat ...
- python 之常用模块
一 认识模块 二 常用模块 (1)re模块 (2)collections模块 一 认识模块 (1)什么是模块 (2)模块的导入和使用 (1)模块是:一个模块就是一个包含 ...
- Python之常用模块--collections模块
认识模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的 ...
- Python自动化开发之python的常用模块
python常用模块 模块的种类:模块分为三种,分别是自定义模块:内置标准模块(即标准库):开源模块(第三方). 以下主要研究标准模块即标准库:标准库直接导入即可,不需要安装. 时间模块:time , ...
- python基础----常用模块
一 time模块(时间模块)★★★★ 时间表现形式 在Python中,通常有这三种方式来表示时 ...
- python(五)常用模块学习
版权声明:本文为原创文章,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明. https://blog.csdn.net/fgf00/article/details/52357 ...
随机推荐
- Git-Runoob:Git 分支管理
ylbtech-Git-Runoob:Git 分支管理 1.返回顶部 1. Git 分支管理 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同 ...
- autoprefixer不起作用的坑
概述 今天同事说,nuxt.js的项目好像没有自动加前缀,我花了很长时间查找原因,最后终于发现,原来是没有加.browserslistrc文件...记录下来,供以后开发时参考,相信对其他人也有用. b ...
- BFC块级格式
BFC块级格式上下文,独立的一个渲染区域 1.同一个BFC的两个相邻盒子间的margin会重叠(垂直方向): 2.BFC内部的盒子在垂直方向上会一个接一个的放置: 3.每个子元素的左外边距与包含块的左 ...
- 《Using Python to Access Web Data》Week4 Programs that Surf the Web 课堂笔记
Coursera课程<Using Python to Access Web Data> 密歇根大学 Week4 Programs that Surf the Web 12.3 Unicod ...
- 【ABAP系列】SAP ABAP 刷新SCREEN的方法
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 刷新SCREE ...
- 应用安全 - Web安全 - 远程控制管理工具 - 汇总
菜刀 蚁剑 冰蝎 DarkCommet ADT windows/upexec/reverse_tcp set PEXEC xxx
- 【Qt开发】设置Qt应用程序图标
[Qt开发]设置Qt应用程序图标 标签:[Qt开发] 首先,准备一个图标,例如:zx.ico,并新建一个文本文档,在里面添加一行: IDI_ICON1 ICON DISCARDABLE"zx ...
- Web安全测试中常见逻辑漏洞解析(实战篇)
Web安全测试中常见逻辑漏洞解析(实战篇) 简要: 越权漏洞是比较常见的漏洞类型,越权漏洞可以理解为,一个正常的用户A通常只能够对自己的一些信息进行增删改查,但是由于程序员的一时疏忽,对信息进行增删改 ...
- 20191127 Spring Boot官方文档学习(4.13)
4.13.Messaging Spring框架为与消息传递系统集成提供了广泛的支持,从使用JmsTemplate简化JMS API到完整的异步接收消息的基础结构.Spring AMQP为高级消息队列协 ...
- spring扩展点之PropertyPlaceholderConfigurer
原理机制讲解 https://leokongwq.github.io/2016/12/28/spring-PropertyPlaceholderConfigurer.html 使用时多个配置讲解 ht ...