python from rookie to master
2020-11-23 10:40:58 0 举报
AI智能生成
Python思维导图
作者其他创作
大纲/内容
语言基础
小整数对象池:【-5,256】,所有对象创建的对象的值在这个区间内,都会是同一个地址,小于等于20个字符的代码也是,避免频繁的申请和销毁地址
大整数对象池子:文本的py。所创建的代码块属于同一个内存空间,所以他们所创建的大整数也在同一个地址
如果因为空间有限,代码都放在一行,可以用;来隔开
python 一行不够写可以用\ 来链接上下两行
python中的整除\\ 服从向下取整的原则
条件循环与其他的语句
while :else:只有在正常结束循环没有break的时候才会输出else里面的语句,作为正常循环结束的一种奖励,continue对其没有影响
多分支的判断;if 判断语句:elif 判断语句: else:
计数循环:for i in range()
遍历循环 for i in liter()
文件遍历循环:for i in file:遍历文件的每一行
条件循环:while
break:跳出整个循环执行循环后的语句,continue:结束单次循环
break:多层次嵌套的循环,break仅跳出当前自己属于的循环,一个break只能跳出一个循环
列表和元组
定义列表元组,可以放整型浮点型,字符串,布尔
数组和元祖的不同在于数组中的类型只能是同一个类型
列表基本操作
索引来取值:list1【0】,数字可以有正负的取值
也可以在字符串的后面直接加索引取值字母:‘apple’【2】
分片操作
[start:end:step]
将结束索引设为0,会得到一个空列表
序列的相加与相乘 ,列表和字符串都属于序列,可以有拼接的操作,和复制操作
in 的属于操作可以判断某一个数值是否属于某一个序列
赋值操作:【i】进行位置的定位再进行 = Newvalue
定位删除元素 : del list1【i】
分片的赋值: list1 【2:5】 = 【1,2,3,】,修改2-4位置的元素值
列表的方法
list1.append(x),x可以是列表,子序列,元素,加到list1的最后面
list1.clear() :清楚列表的所有元素
list1.count(x),计算x在列表中的出现次数
list1.extend()用于在列表的结尾,重新添加一个列表,作用于原来的列表,而两个相加的产生出一个新的列表
list.index(x):找出x元素出现的第一次的位置
pop()默认是将最后的元素弹出,返回值是弹出的元素
insert(位置,新元素) ,不会覆盖,而是新增,别的向后挪一位
remove(元素),将元素移除
.reverse()将元素反放 ,属于字符串的方法,而reversed()则是内置函数
.copy()将列表复制给另一个变量,但是他们的内存地址不同,列表是可变的数据类型
深度复制
sort():排序,作用于原列表,reverse = True参数修改排序的方式
sorted()新生成一个列表,这是内置函数,不是列表的方法,在赋值给一个新的变量,不作用于原来的函数
元组:也是一种序列,但是元组的不可以修改的,是只读的,用‘,’来定义,有时候元组的括号可以省略,元组的类型用tuple()
字符串
字符串的基本操作
字符串的连接+和*操作可以使用
切片操作【star,end:step],步长的正负,正的时候end>star,负数的时候star>end
字符串的转义
/r 表示执行动作后,光标返回到行首
字符串的函数
len()返回字符串的长度值
str()转换,增''
eval()
hex()将括号里面是数字转换为16进制
oct()转化为8进制的函数
chr(u)将unicode的编码转化为对应的字符
ord(x)将字符转化为编码
字符串的方法<a>.<b>
.lower()和 .upper() 全大写或者小写
str.split(sep = None) ,返回值是一个列表将字符串分隔用括号中的函数‘AB*C*D'.split(*)。[AB,C,D]括号中放的是拆开依据
str.count(计数的依据对象),返回值是依据对象的出现次数
str.replace(old,new)返回str副本,所有的old被new所替代
str.center(宽度【,填充对象】)
str.strip(chars) 去除字符串左右两侧的chars字符,如果不填写chars就是去空格,有lstrip和rstrip
str.jion(iter)在iter的中的每个元素的后面都添加一个字符串str,例如’,‘.jion('123')输出是’1,2,3‘
str.find('查找的参数‘【,起始位置,终点位置】) :找到的返回值是找到的第一次出现的位置,没找到返回值是-1,rfind()
字符串的格式化
str.format()槽就是占位符号,参数序号{数字}和{变量名}用关键字来关联,
输出格式的控制{参数序号或者变量名:格式控制标记}6种格式控制标记
填充
填充对齐和宽度是有顺序的,{0:=^20}表示等号填充居中对齐,宽度是20
对齐
<^>
宽度
宽度在填充对齐的后面,也可以直接给宽度
千位符号’,‘
{:,}
精度
精度之前有一个小数点{:.2f}
类型
b,{:b}将数字转为二进制输出
c,{:c}将数字转为对应unicode的字符
d,十进制输出
o和O都是八进制输出
x和X都是16进制输出
a :将数字转化为相对应的unicode编码字符
e,E以科学计数法表示浮点数
f
% 以百分数的形式来表示浮点数
格式化字符串%:通过%传入,再根据要求格式化字符输出
子主题 1
%d、%i 转换为带符号的十进制整数
%o 转换为带符号的八进制整数
%x、%X 转换为带符号的十六进制整数
%e 转化为科学计数法表示的浮点数(e 小写)
%E 转化为科学计数法表示的浮点数(E 大写)
%f、%F 转化为十进制浮点数:.2f
%g 智能选择使用 %f 或 %e 格式
%G 智能选择使用 %F 或 %E 格式
%c 格式化字符及其 ASCII 码
%r 使用 repr() 函数将表达式转换为字符串
%s 使用 str() 函数将表达式转换为字符串
字典dict
字典的创建
将列表转换为字典:list1=[[1,'a'],[2,'b']]; dict1 = dict(list1)
将元祖转换为字典:tuple1 =(a=1,b=2) ;dict1 = dict(tuple1)
字典的基本操作
len():返回的是键值对的数量
查询:dict1[key],返回value的值
改:dict1【key】 = newvalue
key in dict1:判断key在dict1中吗
字典中的键可以是任意的不可变的类型
列表序列的迭代
for key in dict1: 得到的是所有的键的值 或者 在此基础上 print(key,'=',dict1[key],sep = '')
for key,values in dict1.items(): 同时得到字典中的键和value的值
并行迭代:同时获得两个或者多个序列的值。list1 = 【1,2,3,4】list2 = 【5,3,5,5】 for i in range(len(list1)): print(list(i),list2(i))
压缩迭代: for i in zip(list1,list2): print(i) zip函数的将两个列表挨个合并成一个元祖
反转排序 :利用reversed(),将列表反转再遍历
字典的方法
clear():清空字典 。#因为字典类型是可变的类型,所以清空其中的第一个关联其他的关联也会清空
copy()
get()
update()
pop(x)如果没有 x也不会报错,popitems()默认弹出最后一个
setdefault(key,values)添加键值对,但是区别是如果添加的是原来字典里面有的就不会覆盖。
集合:去重
方法
添加:add,upda
删除:remove,discard,pop,clear
基本
add() 为集合添加元素
clear() 移除集合中的所有元素
copy() 拷⻉贝⼀一个集合
pop() 随机移除元素
remove() 移除指定元素
union 返回两个集合的并集
update() 给集合添加元素
difference() 返回多个集合的差集
difference_update() 移除集合中的元素,该元素在指定的集合也存在。
discard() 删除集合中指定的元素
intersection() 返回集合的交集
intersection_update() 删除集合中的元素,该元素在指定的集合中不不存在。
isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回False。
issubset() 判断指定集合是否为该⽅方法参数集合的⼦子集。
issuperset() 判断该⽅方法的参数集合是否为指定集合的⼦子集
symmetric_difference() 返回两个集合中不不重复的元素集合。
symmetric_difference_update()移除当前集合中在另外⼀一个指定集合相同的元素,并将另外⼀一个指定集合中不不同的元素插⼊入到当前集合中
函数
可变和不可变的类型
#不可变类型,在函数里修改的时候的闭包的,函数内部会自己生成一个同名的局部变量变量,不修改全局变量
x = 20
s = 'hello world'
def test(xa,d):
x = 40
s = '你好
test(x,s)
print(x,s) ,不会被修改还是输出20,helloworld
#可变类型,在函数中可以被修改,不需要global声明
x = [20]
s = ['hello world']
def test(xa,d):
x[0] = 40
s[0] = '你好世界'
test(x,s)
关键字参数和设置默认值:func(name = ‘cdh',age = 18)
设置可变参数:func(*args,**kwargs)
将序列作为参数变量传入,需要拆包,元组,列表用*,字典用**
作用域:函数内部可以看见外部不可变变量,但是不能修改,只能访问,隐藏全局变量
修改全局变量
报错
a = 10
def func2():
print(a)
a = 20
func2()
因为先用print访问到的a是全局变量,后面修改它就会报错
不报错
a = 10
def func2():
a = 20
print(a)
func2()
这个因为是封闭,先定义了一个局部的同名变量,并未修改到全局变量
当函数调用时,局部变量量被创建,当函数调用完成后这个变量量就不不能够使⽤用了了
嵌套函数:内层函数可以修改外层函数的可变变量,但是不可以修改不可变变量,需要nonlocal
访问全局变量,依然需要在内部函数的开头声明global
不可以在外部直接调用内部函数
闭包:函数内部定义的变量,在函数的外部不可以被访问和修改,被封闭起来了
函数可以通过return将函数内部变量,甚至是函数的本身抛出,函数抛出的时候需要用变量接一下再调用变量函数
闭包的下:同级内部函数访问:同级的可以相互调用,但是访问的话某一个值的话,可以通过将值return的方法实现
装饰器:重修修饰不够完美的函数:先定义函数,再调用函数的的上面加@decorate
定义装饰器:def decorate(func):
@decorate 放在定义函数的前面,再调用函数
在闭包的状态下,传入函数作为参数
装饰器的本质:原函数换成装饰器里的内部函数,而原函数变为func()
注意原函数,func(),inner()函数的参数数量应该一致
闭包:有内外函数,内函数应用了外部函数的值,外函数有返回值,返回的是内部函数
递归:函数自己调用自己,需要设置出口
函数之间的相互赋值
a = func()是调用后,将func的返回值赋值给了a
a = func,是直接将函数给了变量a接着,所以同样可以a()来调用函数,并且del func是删除了变量,二没有删除函数
print('这里是函数之间的复制')
def func():
print('hello world')
a = func
a()
print(id(func))
print(id(a))
print(func is a)
del func
a() #依然可以调用a
return返回值
一个函数中可以有多个return语句句,但是只要有一个return语句句被执行行到,那么这个函数就会结束了了,因此后⾯面的return没有什么用
return 多个返回值,默认用元祖来接,装包
拆包,用多个元素来接rtuen 打包的多个值,就会按照顺序拆包
匿名函数lambda:参数:返回值
两种用法1.用一个变量接受这个函数,在调用这个变量
用法二:把匿名函数当作一个参数传给另一个函数
dict1.sort(函数,reverse=): .sort(lambda x:x[key])
filter(函数,可迭代对象):filter(lambda x:x>10,list1)
map(函数,可迭代对象):让可迭代对象都执行,函数中的内容。map(lambda x :x+2,list1)
lambda的判断:lambad x:x if x%2==0 else:x+3
reduce(函数,序列):reduce(lambda x,y:x + y[key],dict1)
回调函数:def huidiao(a,b,fuc)
常见内置的函数
abs()绝对值函数
all(list1):将列表里面的数据全部转为布尔值,如果都是真,则返回真
any,只要有一个元素是真就是返回真
dir(对象或者序列):列出他们所有可以用的方法
exit(结束码)结束程序,同时返回给已指定的结束码
help(x)查看x的帮助文档
globals查看所有全局变量,locals查看所有局部变量
isinstance() 判断一个对象是不是由一个类创建出来的,issubclass()判断一个类是否是另一个类的子类
iter():获取可迭代对象的迭代器
next:for……in循环本身就是调用迭代器的next方法
open()用来打开一个文件
round()四舍五入
sum()求和
repr()把对象转化为字符串
高阶函数
一个函数A是另一个函数B的返回值 A()(),来执行B函数
函数作为参数传入另一个函数,在其中进行执行
类和对象
面向对象的优点:继承:继承其他类的属性和方法,封装:对外隐藏对象的工作细节和多态:对象在不同的场景下有不同的动作.
创建自己的类:Class Person: 类名首个字母大写,并且采用驼峰式,继承的父类可以省略不写
class Person():
name = 'cdj' #设置类属性
age = 18
sex = 'man'
def setName(self,name): #设置类方法
self.name = name
def getName(self):
return self.name #要有self
p1 = Person()
p1.socre = 80 #设置对象的新属性,类中没有
p1.age = 25 #改变对象自己中的属性
# print(p1.socre)
# print(p1.age)
print(p1.getName()) #使用方法
修改类中的属性:Person.name = 'CHDENGJIAN'
方法和私有化
在方法名,和属性名字的面前加__,就可以实现方法和属性名的私有化。
实际上并没有真正的私有化,而是在在前面加了__类名,def __serName() 变成了_Person__setName
返回值有None
用return,没有None
class Person1():
__name = 'cdj'
def __pr(self):
return'hello world'
def pr(self):
return '你好'
p2 = Person1()
# print(p2._Person1__name)
print(p2._Person1__pr())
print(p2.pr())
有None
class Person1():
__name = 'cdj'
def __pr(self):
print('hello world')
def pr(self):
print( '你好)'
p2 = Person1()
# print(p2._Person1__name)
print(p2._Person1__pr())
print(p2.pr())
方法
普通方法
直接在类里面定义的方法,可以在这里面调用私有方法
重写普通方法:当子类继承父类,子类中就会有父类和方法属性,然而在定义子类时候既有继承父类,又重新定义了一个和父类同名的方法,就会重写父类的方法
覆盖方法名只看方法的名字是否相同,不看参数是否一致
super()函数,子类访问超类需要用这个函数,返回超类对象,super()可以不带参数,也可以带两个参数,第一个是当前类的类型,第二个是self
super().跟上需要调用的父类的方法或者属性
类方法
@
静态方法
魔术方法
def __init__(self):构造方法,类在实例化之前就会调用构造方法。
子类覆盖父类init方法,使得父类中的init的变量找不到
class Person:
def __init__(self):
print('这个方法已经被调用')
self.name = 'bill'
def getname(self):
return self.name
def setname(self,name):
self.name = name
class Man(Person):
def __init__(self):
print('初始化')
self.age = 18
def getage(self):
return self.age
def setage(self,age):
self.age = age
m1 = Man()
print(m1.age)
#m1.name和m1.getname都报错,因为父类中的name被覆盖,所以没有name这个变量
def __new__(self):创建内存空间的函数
继承
定义:子类继承父类,子类可以使用父类的属性和方法
检测继承关系,判断类和类之间的关系:用issubclass(子,父)。返回布尔类型
查看所有的父类:print(Person.__base__)
继承的关系
is a
has a
多类继承
如果一个类中定义了两个同名的方法,默认后面的 会覆盖前面的,先调用子类中的同名方法,再逐层向上
多类继承:现在是广度优先
多态(接口)
单例模式
异常
try:
可能出错的代码
except 错误类型:
出错后执行代码
else:在不发生异常的时候才回去执行
fianlly:无论有误异常都回去执行的代码,一般后面放关闭资源的代码
主动抛出的异常raise
raise Exception:执行就抛出Exception的异常
自定义异常类
class MyException(Exception):
pass
a = 10
if a>5:
raise MyException('这是我自己定义的异常')
捕捉异常
try:
可能出错的代码
except :
只要出错后执行代码
捕捉多个异常
try:
可能出错的代码
except 异常类型1:
异常类型1后执行代码;
一般最后要跟上一个except Exception:包含著没有包括在内的异常
或者最后一个直接是except:
同一代码块接受多个异常
有时候会返回多个异常,然而这几个异常的处理方式都是一样的,就需要同时接受多个异常
except (异常1,异常2,异常3等):
同一操作
捕捉对象
虽然有的时候都是抛出同一个类型错误,但是其中还是有着差别,所以需要一个异常对象来,在判断异常的同时还要接受异常返回的 详细信息
except (Exception as a:
print(a)
多层嵌套的函数异常
方法嵌套和属性
模块和库
time库
时间的获取
获取时间戳,time.time(),计算机内部时间值,从1970年1月1日到当前时间的时间值
time.ctiem()返回字符串,以一种人类可读的方式表示
time.gmtime()获取计算机可以处理的时间格式,返回值是关键字的元祖
时间的格式化输出
stftime(模版,时间参数)将时间模版的样式输出,模版需要用字符串,例如t = time.gmtime(),time.strftime('%Y-%m-%d %H:%M:%S',t)
时间格式化空字符,年%Y,%m是月份,%B是月份名称,%b是月份名称缩写,%d日期,%A是星期,%a是星期缩写,%H24小时,%h12小时进制,%M分钟,%S小时,%p是上下午
strptime(字符串,模版),将字符串变为模版格式的时间,转化为计算机可以操作的时间,TimeStr = ’2018-01-26 12:55:20‘.time.strptime(TimeStr,'%Y-%m-%d %H:%M%:S)
程序记时(测量起止动作经过时间)
测量时间:perf_count()获取计算机cpu时钟的时间,调用连续调用时间差才有意义。end - star
sleep(s),让程序休眠s秒的时间
random库
基本的两个函数
random.random()产生从0到1的随机数
random().seed();产生种子,不设置默认种子为当前系统时间,种子相同产生的随机数也相同
常用函数
randint(a,b)产生ab,包含ab包含ab之间的整数
randrange(a,b[,c]),生成带步长的整数
getrangbits(k)产生k比特位长的整数
uniform(a,b)产生ab之间的小数
random.choice(序列),随机返回序列中的一个元素
random.shuffle(序列)将序列随机打乱后再返回
TCP,UDP
IP地址与子网掩码的与运算,出网络地址,全-为网络位,全1是广播位,子网掩码采用点分十进制,ip地址只有在一个网段才能局域网通信
IP地址分为abcde类,不同的网段号,不同的主机号
dhcp地址池:用来自动分配IP地址,一般家用dhcp就是路由器,默认网关:用来如果局域网访问一个IP地址,而这个地址又不在局域网内部,那么它就会去找默认网关来先外查询,一般家用默认网关就是路由器
dns:域名解析服务器:
端口:不同电脑之间发送数据通过端口号来识别信息给那个程序
pid:同一个电脑用pid来识别不同的程序
socket:套接字,通信
udp:不需要建立链接的不安全通信
发送方:import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.sendto('hello'.encode('utf8')
('192.168.31.199',9000))
s.close()
接受方:
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
content = s.recvfrom(1024)
print(content)
s.close()
tcp:先要建立链接的安全通信
发送方import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.1.12',9000))#先和要通信的一方建立链接
s.send('hello'.encode('utf8')) #再发送数据
客户端发请求,接受文件:import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('192.168.0.1',9000))
file_name = input("请输入您想下载的文件名:")
s.send(file_name.encode('utf8'))
with open(file_name,'wb') as file:
while True:
content = socket.recv()
if content == None:
break
file.write(content)
s.close()
接受方#服务代码
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('192.168.1.12',9000))#绑定服务器自身的端口号
s.listen(128)
client_socket,client_addr = s.accept() #拆包接收返回值:发送对象的socket,发送对象的地址,端口号
clint_data = client_socket.recv()#在socket对象中用recv方法来调出内容数据data
import os
服务器接受请求,发文件import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('192.168.0.1',9000))
s.listen(128)
client_socket,client_addr = s.accept()
file_name = client_socket.recv(1024)
if os.path.isfile():
with open(file_name,'rb') as rdsteam:
content = rdsteam.read()
s.send(content)
else:
print('文件不存在')
迭代器生成器,推导式
推导式用【】和for遍历筛选出新的值
列表推导式
【表达式(这还可以再次操作) for 变量 in 旧列表 if 条件】
newlist = [name for name in list1 if len(name) >3]
推导式中有if else,for 放在 if else 的后面
newlist = 【employee['salary']+200 if empolyee['salart']>5000 else empolyee['salary'] + 500 for empolyee in list1]
集合推导式
new_set = [ x for x in set1]
字典推导式
和其他推导式相同,只是有两个变量
newdict = {key:value for key,.value in dict1 if value>3}
生成器(遍循环遍计算生成)——节省内存,但是不可以索引
(1)通过列表推导式得到生成式
将【】换成()得到生成器
g = (x>3 for i in range(10))
调用方法一:g.__next__()
调用方法二:next(g)
如果调用生成器,然而其中已经没有元素就会报错
生成器和循环的结合使用
g = (x*3 for i in range(10))
while True:
try:
e = next(g)
print(e)
except:
print('没有元素了‘)
break
(2)(通过函数+yield) 变成生成器,没有值返回的时候要返回None
(1)定义一个函数,函数中使用yield关键字
(2)调用函数,接受调用结果(不管有没有返回值)
(3)得到的结果就是生成器
(4)借助next(),或者.__next__()
def func():
n = 0
while True:
n+= 1
yield n
g = func()
print(g.__next__())
生成器的作用
#生成器的运用
def task1(n):
for i in range(n):
print('正在搬第{}砖'.format(i+1))
yield None
def task2(n):
for i in range(n):
print("正在听第{}首歌".format(i+1))
yield None
g1 = task1(5)
g2 = task2(5)
while True:
try:
g1.__next__()
g2.__next__()
time.sleep(1)
except:
break
迭代器
正则表达式(re模块)
match 方法没有匹配成功就会返回none,从头开始匹配,成功返回第一个对象,只要开头匹配不成功就不成功
#match只要开头匹配不成功就是不成功
s = '迪丽热巴古力娜扎'
result = re.match('热吧',s)
print(result)
result = re.match('热巴',s)
print(result)
result = re.match('迪丽',s)
print(result)#<re.Match object; span=(0, 2), match='迪丽'>
search,匹配整个字符串,匹配成功就会返回一个span的匹配位置的对象,可以用对象的方法span()输出位置,可以用对象的group()提取到匹配部分的内容,但是匹配到一个成功就停止后面的匹配
s = '迪丽热巴古力娜扎'
result = re.search('古力',s)
print(result)
print(result.span())#(4, 6)
print(result.group())#古力
re.findall,匹配整个字符串,表示找一个继续往下找,一直到找到字符串结尾到一个
#找到符合数字字母数字格式的字符串,findall和search
s1 ='1w2f4thj5l4'
result = re.search('[0-9][a-zA-Z][0-9]',s1)
print(result) #<re.Match object; span=(0, 3), match='1w2'>,找到一个就不会再向下去找
result = re.findall('[0-9][a-zA-Z][0-9]',s1)
print(result) #['1w2', '5l4']
使用总结(范围+量词)
字符集,在正则里面[]表示一个字符的取值范围[0-9]表示0-9的数字,[a-zA-Z],表示或者的关系
【abcd】表示匹配其中之一
【ab】【cd】表示开头是a或者b,第二位是c或者d,相当于字符串的拼接
^再search中表示从头开始挨个校验,$表示直到结尾
.小数点表示\n之外的任意字符串,表示一个位置,对象没有的这个位置还是不会成功。例如:bin.和bin不会成功
^ 表示从头开始完整的匹配,$表示匹配到结尾,拉一个字符串整个拿来匹配
正则表示式的预定义,\s表示空白(格),\b边界,再正则中为了防止\的转义再前面加r防止变成字符串的转义,\d数字,\w表示[0-9a-zA-Z_],上面大写的表示非的关系,以上只能匹配一个字符,的话还需要靠量词
量词
* 表示>=0个,0到n次
+ >=1,至少出现一次
? 表示或者无,1或者0 ,可有可无
[m]固定位数,[m,]大于等于m位,[m,n]大于等于m,并且小于等于n位数。
‘ | ’表示或者,[a|b|c]或者a或者b或者c,加大范围
分组表示
用()实现分组
#验证邮箱 163,qq,126邮箱
mail = '870429943@qq.com'
result = re.match(r'\w{5,}@(qq|126|163)\.(com|cn)',mail)
print(result)
print(result.group(1))
(ABC){3}表示ABC重复3次,abc{3}表示c重复3次
数引用分组,\1引用第一组,\2引用第二组如此类推
组之间有默认序号,按照出现向后排序,从1开始
调用组,用接收的对象.group(序号)调用
给组起名:(?p<组名>正则表达式)
引用组的名字(?P=组名)
分组操作
n = '100'
result = re.match(r'’[1-9]?\d$|100$'‘,n)
print(result)
#qq号码5-11位,不能0开头
n= '870429943'
result = re.search(r'^[1-9][0-9]{4,10}$',n)
print(result)
贪婪匹配和非贪婪匹配
python中的默认是贪婪匹配的,总是尝试匹配尽可能多的符合要求的字符
在量词的后面加?,可以使得贪婪变成非贪婪匹配:*?,??,+?,{m,n}?
非贪婪则相反,总是尽可能匹配少的字符
0 条评论
下一页