一、time模块
1.时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型
print(time.time())时间戳
2.格式化的时间字符串(Format String)
#格式化的字符串# print(time.strftime('%Y-%m-%d %H:%M:%S'))# print(time.strftime('%Y-%m-%d %X'))
3.结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
结构化的时间# print(time.localtime())# print(time.localtime().tm_year)# print(time.gmtime())print(time.localtime(1496807630))#将unixtime时间转换成各式话时间结果:time.struct_time(tm_year=2017, tm_mon=6, tm_mday=7, tm_hour=11, tm_min=53, tm_sec=50, tm_wday=2, tm_yday=158, tm_isdst=0)print(time.strftime('%Y %X',time.localtime()))结果:2017 12:01:41print(time.strptime('2017-06-04 11:59:59','%Y-%m-%d %X'))结果:time.struct_time(tm_year=2017, tm_mon=6, tm_mday=4, tm_hour=11, tm_min=59, tm_sec=59, tm_wday=6, tm_yday=155, tm_isdst=-1)print(time.ctime(123123132))结果:Mon Nov 26 08:52:12 1973print(time.asctime(time.localtime()))结果:Wed Jun 7 12:03:44 2017
二、random模块
从列表中随机选出一个ip地址,应用场景爬虫import randomproxy_ip=[ '1.1.1.1', '1.1.1.2', '1.1.1.3', '1.1.1.4',]ip=random.choice(proxy_ip)print(ip)
# import random# print(random.sample([1,'23',[4,5]],2))#随机做两个组合# 结果:[1, '23']
#验证码def v_code(n=5): res='' for i in range(n):#n长度 num=random.randint(0,9)#0-9的数字 s=chr(random.randint(65,90))#65-90是a到z的asell码 add=random.choice([num,s])#从num和s中选出一个 res+=str(add)#拼接字符 return resprint(v_code(6))
import random print(random.random())#(0,1)----float 大于0且小于1之间的小数 print(random.randint(1,3)) #[1,3] 大于等于1且小于等于3之间的整数 print(random.randrange(1,3)) #[1,3) 大于等于1且小于3之间的整数 print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5] print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合 print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716 item=[1,3,5,7,9]random.shuffle(item) #打乱item的顺序,相当于"洗牌"print(item)
三、os模块
与操作系统交互
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cdos.curdir 返回当前目录: ('.')os.pardir 获取当前目录的父目录字符串名:('..')os.makedirs('dirname1/dirname2') 可生成多层递归目录os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirnameos.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirnameos.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印os.remove() 删除一个文件os.rename("oldname","newname") 重命名文件/目录os.stat('path/filename') 获取文件/目录信息os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'os.system("bash command") 运行shell命令,直接显示os.environ 获取系统环境变量os.path.abspath(path) 返回path规范化的绝对路径os.path.split(path) 将path分割成目录和文件名二元组返回os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素os.path.exists(path) 如果path存在,返回True;如果path不存在,返回Falseos.path.isabs(path) 如果path是绝对路径,返回Trueos.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回Falseos.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回Falseos.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间os.path.getsize(path) 返回path的大小
os路径处理#方式一:推荐使用import os#具体应用import os,sys #获取项目的跟目录的两种方式possible_topdir = os.path.normpath(os.path.join( os.path.abspath(__file__), os.pardir, #上一级 os.pardir, os.pardir))sys.path.insert(0,possible_topdir)#方式二:不推荐使用os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
四、sys模块
1 sys.argv 命令行参数List,第一个元素是程序本身路径2 sys.exit(n) 退出程序,正常退出时exit(0)3 sys.version 获取Python解释程序的版本信息4 sys.maxint 最大的Int值5 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值6 sys.platform 返回操作系统平台名称
import sys,timefor i in range(50): sys.stdout.write('%s\r' %('#'*i)) sys.stdout.flush() time.sleep(0.1)'''注意:在pycharm中执行无效,请到命令行中以脚本的方式执行'''
五 shutil模块
1.将文件内容拷贝到另一个文件中
import shutilshutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
2.拷贝文件
shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
3.仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
4.shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flagsshutil.copystat('f1.log', 'f2.log') #目标文件必须存在
5.shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
import tarfile# 压缩>>> t=tarfile.open('/tmp/egon.tar','w')>>> t.add('/test1/a.py',arcname='a.bak')>>> t.add('/test1/b.py',arcname='b.bak')>>> t.close()# 解压>>> t=tarfile.open('/tmp/egon.tar','r')>>> t.extractall('/egon')>>> t.close()tarfile压缩解压缩
六 json&pickle模块
1.json
1.1json在python中的应用
在python中有些时候eval也可和json.load同样的功能但是遇到特殊的字符入Null,eval就无法转换了这时候就必须用json模块。
import jsonx="[null,true,false,1]"print(eval(x)) #报错,无法解析null类型,而json就可以print(json.loads(x))
1.2 什么是序列化
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
import json#序列化的过程:dic---->res=json.dumps(dic)---->f.write(res)dic={ 'name':'alex', 'age':9000, 'height':'150cm',}res=json.dumps(dic)print(res,type(res))with open('a.json','w') as f: f.write(res)
1.2 为什么要序列化
1:持久保存状态
需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,'状态'会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。
内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。
在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。
具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。
2:跨平台数据交互
序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
json
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
import json#反序列化的过程:res=f.read()---->res=json.loads(res)---->dic=reswith open('a.json','r') as f: dic=json.loads(f.read()) print(dic,type(dic)) print(dic['name'])
json操作
#json的便捷操作import jsondic={ 'name':'alex', 'age':9000, 'height':'150cm',}json.dump(dic,open('b.json','w'))
2.pickle
import pickle dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#j=pickle.dumps(dic)print(type(j))# f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'f.write(j) #-------------------等价于pickle.dump(dic,f) f.close()#-------------------------反序列化 import picklef=open('序列化对象_pickle','rb') data=pickle.loads(f.read())# 等价于data=pickle.load(f) print(data['age'])
pickle.load(open('c.pkl','rb'))
json 和pickle对比
import pickle# dic={'name':'alex','age':13}# print(pickle.dumps(dic))# with open('a.pkl','wb') as f:# f.write(pickle.dumps(dic))# with open('a.pkl','rb') as f:# d=pickle.loads(f.read())# print(d,type(d))# dic={'name':'alex','age':13}# pickle.dump(dic,open('b.pkl','wb'))# res=pickle.load(open('b.pkl','rb'))# print(res,type(res))#import jsonimport pickle# def func():# print('from func')# json.dumps(func)# 报错,json不支持python的函数类型# f=pickle.dumps(func)# print(f)# pickle.dump(func,open('c.pkl','wb'))# res=pickle.load(open('c.pkl','rb'))# print(res)# res()
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系
七 shelve模块
import shelvef=shelve.open(r'sheve.txt')f['fff']={'name':'egon','age':18,'height':'180cm'}print(f['fff']['name'])f.close()
八 xml模块
2 2008 141100 5 2011 59900 xml数据 69 2011 13600
# print(root.iter('year')) #全文搜索# print(root.find('country')) #在root的子节点找,只找一个# print(root.findall('country')) #在root的子节点找,找所有import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml")root = tree.getroot()print(root.tag) #遍历xml文档for child in root: print('========>',child.tag,child.attrib,child.attrib['name']) for i in child: print(i.tag,i.attrib,i.text) #只遍历year 节点for node in root.iter('year'): print(node.tag,node.text)#---------------------------------------import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml")root = tree.getroot() #修改for node in root.iter('year'): new_year=int(node.text)+1 node.text=str(new_year) node.set('updated','yes') node.set('version','1.0')tree.write('test.xml') #删除nodefor country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')#在country内添加(append)节点year2import xml.etree.ElementTree as ETtree = ET.parse("a.xml")root=tree.getroot()for country in root.findall('country'): for year in country.findall('year'): if int(year.text) > 2000: year2=ET.Element('year2') year2.text='新年' year2.attrib={'update':'yes'} country.append(year2) #往country节点下添加子节点tree.write('a.xml.swap')
创建xmlimport xml.etree.ElementTree as ET new_xml = ET.Element("namelist")name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})age = ET.SubElement(name,"age",attrib={"checked":"no"})sex = ET.SubElement(name,"sex")sex.text = '33'name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})age = ET.SubElement(name2,"age")age.text = '19' et = ET.ElementTree(new_xml) #生成文档对象et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式
九 configparser模块
import configparserconfig=configparser.ConfigParser()config.read('a.cfg')#删除整个标题section2config.remove_section('section2')#删除标题section1下的某个k1和k2config.remove_option('section1','k1')config.remove_option('section1','k2')#判断是否存在某个标题print(config.has_section('section1'))#判断标题section1下是否有userprint(config.has_option('section1',''))#添加一个标题config.add_section('egon')#在标题egon下添加name=egon,age=18的配置config.set('egon','name','egon')config.set('egon','age',18) #报错,必须是字符串#最后将修改的内容写入文件,完成最终的修改config.write(open('a.cfg','w'))
test.ini配置文件
# 注释1; 注释2[section1]k1 = v1k2:v2db=pymysql+mysql://egon:123@192.168.2.3/db1max_conn=30enable=0[section2]k1 = v1
1.获取所以节点
import configparserconfig=configparser.ConfigParser()config.read('test.ini')#获取所以节点print(config.sections())结果:['section1', 'section2']
2.获取节点下的所以键值对
import configparserconfig=configparser.ConfigParser()config.read('a.ini',encoding='utf-8')res=config.items('section1')print(res)结果:[('k1', 'v1'), ('k2', 'v2'), ('db', 'pymysql+mysql://egon:123@192.168.2.3/db1'), ('max_conn', '30'), ('enable', '0')]
3.获取指定节点下的所有key
config=configparser.ConfigParser()config.read('a.ini',encoding='utf-8')res=config.options('section1')print(res) 结果:['k1', 'k2', 'db', 'max_conn', 'enable']
4 获取指定节点下指定key的值
import configparserconfig=configparser.ConfigParser()config.read('test.ini',encoding='utf-8')res1=config.get('bitbucket.org','user')res2=config.getint('topsecret.server.com','port')res3=config.getfloat('topsecret.server.com','port')res4=config.getboolean('topsecret.server.com','ForwardX11')print(res1)print(res2)print(res3)print(res4)'''打印结果:hg50022.0False'''
5 检查、删除、添加节点
import configparser #检查节点config=configparser.ConfigParser()config.read('a.ini',encoding='utf-8')has_sec=config.has_section('section1')检查是否存在节点
print(config.has_option('section1','enable'))检查某个节点下是否存在key
print(has_sec)##添加修改config.add_section('egon')config.set('egon','han','18')#如果存在修改config['egon']['han']='28'config.write(open('m.ini','w'))
#删除节点config.remove_section('egon')config.write(open('test.ini','w'))
6 检查、删除、设置指定组内的键值对
import configparserconfig=configparser.ConfigParser()config.read('m.ini',encoding='utf-8')#检查has_sec=config.has_option('section2','k1') #bsection2下有一个键k1print(has_sec) #打印True#删除节点下的keyconfig.remove_option('section2','k1')删除section2节点下的k1config.write(open('m.ini','w'))#设置config.set('section1','k1','han')#设置section1节点下k1 的值位hanconfig.write(open('m.ini','w'))
十 hashlib模块
hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
三个特点:1.内容相同则hash运算结果相同,内容稍微改变则hash值则变2.不可逆推3.相同算法:无论校验多长的数据,得到的哈希值长度固定。1.加密
m=hashlib.md5()m.update('123456'.encode('utf-8'))print(m.hexdigest())得到的md5值:e10adc3949ba59abbe56e057f20f883e
import hashlib m=hashlib.md5() m.update('12'.encode('utf-8'))#累加进去的 m.update('3456'.encode('utf-8')) print(m.hexdigest()) #e10adc3949ba59abbe56e057f20f883e
2.将文件内容加密
import hashlibm=hashlib.md5()with open('md','rb') as f: for line in f: print(line.strip()) m.update(line.strip())#相当于把文档的内容追加是累加 md5_num=m.hexdigest() print(md5_num)#结果:b'1'c4ca4238a0b923820dcc509a6f75849bb'2'c20ad4d76fe97759aa27a0c99bff6710b'3'202cb962ac59075b964b07152d234b70b'4'81dc9bdb52d04dc20036dbd8313ed055b'5'827ccb0eea8a706c4c34a16891f84e7bb'6'e10adc3949ba59abbe56e057f20f883e
3.sha256 hashlib的升级比原有的为数要长
import hashlibs=hashlib.sha256()s.update('123456'.encode('utf-8'))print(s.hexdigest())
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
4.撞库
import hashlibpasswod=['123456','12345678','123456789']def make_pass(passwod): dic={} for pwd in passwod: m=hashlib.md5() m.update(pwd.encode('utf-8')) dic[pwd]=m.hexdigest() return dicdef code(c,pwd_dic): for k,v in pwd_dic.items(): if v ==c: print('密码是%s'%k)code('e10adc3949ba59abbe56e057f20f883e',make_pass(passwod))
十一 suprocess模块
运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。# import subprocess## res=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)# print(res)# print(res.stdout.read().decode('gbk'))import subprocess# res=subprocess.Popen('diasdfasdfr',shell=True,# stderr=subprocess.PIPE,# stdout=subprocess.PIPE)# print('=====>',res.stdout.read())# print('=====>',res.stderr.read().decode('gbk'))#ls |grep txt$res1=subprocess.Popen(r'dir E:\wupeiqi\s17\day06',shell=True,stdout=subprocess.PIPE)# print(res1.stdout.read())res=subprocess.Popen(r'findstr txt*',shell=True, stdin=res1.stdout, stderr=subprocess.PIPE, stdout=subprocess.PIPE)print('===>',res.stdout.read().decode('gbk'))#管道取一次就空了print('===>',res.stdout.read().decode('gbk'))print('===>',res.stdout.read().decode('gbk'))print('===>',res.stdout.read().decode('gbk'))print('===>',res.stdout.read().decode('gbk'))print('===>',res.stdout.read().decode('gbk'))print('===>',res.stdout.read().decode('gbk'))
十二 logging模块
import logging'''一:如果不指定filename,则默认打印到终端二:指定日志级别: 指定方式: 1:level=10 2:level=logging.ERROR 日志级别种类: CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0三:指定日志级别为ERROR,则只有ERROR及其以上级别的日志会被打印'''logging.basicConfig(filename='access.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=10)logging.debug('debug')logging.info('info')logging.warning('warning')logging.error('error')logging.critical('critical')logging.log(10,'log') #如果level=40,则只有logging.critical和loggin.error的日志会被打印
可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。日志格式
%(name)s | Logger的名字,并非用户名, |
%(levelno)s | 数字形式的日志级别 |
%(levelname)s | 文本形式的日志级别 |
%(pathname)s | 调用日志输出函数的模块的完整路径名,可能没有 |
%(filename)s | 调用日志输出函数的模块的文件名 |
%(module)s | 调用日志输出函数的模块名 |
%(funcName)s | 调用日志输出函数的函数名 |
%(lineno)d | 调用日志输出函数的语句所在的代码行 |
%(created)f | 当前时间,用UNIX标准的表示时间的浮 点数表示 |
%(relativeCreated)d | 输出日志信息时的,自Logger创建以 来的毫秒数 |
%(asctime)s | 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
%(thread)d | 线程ID。可能没有 |
%(threadName)s | 线程名。可能没有 |
%(process)d | 进程ID。可能没有 |
%(message)s | 用户输出的消息 |
十三 re模块
一:什么是正则?
正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
生活中处处都是正则:
比如我们描述:4条腿
你可能会想到的是四条腿的动物或者桌子,椅子等
继续描述:4条腿,活的
就只剩下四条腿的动物这一类了
二:常用匹配模式(元字符)
1.\w匹配字符数字下划线 print(re.findall('\w','as213df_*|')) 结果:['a', 's', '2', '1', '3', 'd', 'f', '_']2.\W匹配非字符数字下划线 print(re.findall('\W','as213df_*|'))结果:['*', '|']3.print(re.findall('a\wb','a_b a3b aEb a*b'))#匹配a b直接的匹配字符数字下划线结果:['a_b', 'a3b', 'aEb']4.匹配任意空白字符 等价于【\t\n\r\f】print(re.findall('\s','a b\nc\td'))结果[' ', '\n', '\t']5.\S匹配任意非空字符print(re.findall('\S','a b\nc\td'))结果['a', 'b', 'c', 'd']6.匹配任意数字,等价于[0-9]print(re.findall('\d','a123bcdef'))结果['1', '2', '3']7.\D匹配任意非数字print(re.findall('\D','a123bcdef'))结果['a', 'b', 'c', 'd', 'e', 'f']8.匹配字符\nprint(re.findall('\n','a123\nbc\ndef'))结果['\n', '\n']9.匹配\tprint(re.findall('\t','a123\tbc\td\tef'))结果['\t', '\t', '\t']10.匹配字符 ‘h’print(re.findall('^h','hello egon hao123'))结果[‘h’]print(re.findall('^h','hello egon hao123'))结果[]11.匹配字符串末尾print(re.findall('3$','e3ll3o e3gon hao123'))结果['3']12 匹配任意字符除了换行#匹配a和b中件除了换行的任意字符print(re.findall('a.c','abc a1c a*c a|c abd aed ac'))结果['abc', 'a1c', 'a*c', 'a|c']print(re.findall('a.c','abc a1c a*c a|c abd aed a\nc',re.S)) #让点能够匹配到换行符结果['abc', 'a1c', 'a*c', 'a|c', 'a\nc'] 13. #匹配a开头包含“1”,"2",“\n” 并且以c结尾的字符 print(re.findall('a[1,2\n]c','a2c a,c abc a1c a*c a|c abd aed a\nc')) 结果 ['a2c', 'a,c', 'a1c', 'a\nc'] 14.匹配a开头包含0-9并且c结尾的字符
print(re.findall('a[0-9]c','a2c a11c abc a1c a*c a|c abd aed a\nc')) 结果['a2c', 'a1c'] 15.匹配开头a包含0-9 a-z A-Z * -并且以c结尾的字符
print(re.findall('a[0-9a-zA-Z*-]c','a1c abc a*c a-c aEc a-1c')) 结果:['a1c', 'abc', 'a*c', 'a-c', 'aEc'] 16.a开头b结尾不包含0-9数字的字符
print(re.findall('a[^0-9]c','a1c a2c a*c a-c aEc')) 结果:['a*c', 'a-c', 'aEc'] 17.匹配以a开头b最少0最大无线
print(re.findall('ab*','a ab b'))
结果
print(re.findall('ab*','a ab baaa abbbbbbbbbbbbbbbb ac'))
print(re.findall('ab*','bbbbbb')) 结果[]
18.“+” a开头b最少得有一个
print(re.findall('ab+','a')) 结果:[]
print(re.findall('ab+','bbbbbb')) 结果:[]
19.ab开头结尾包含1或者2或者3
print(re.findall('ab[123]','ab1 ab2 ab3 bbbbb1')) 结果['ab1', 'ab2', 'ab3'] 20.ab开头1、2、3结尾最少包含1个
print(re.findall('ab[123]+','ab11111111 ab2 ab3 abc1')) 结果:['ab11111111', 'ab22222222', 'ab3']
print(re.findall('ab[123]+','ab1 ab2 ab3 ab4 ab123'))
结果:['ab1', 'ab2', 'ab3', 'ab123']
print(re.findall('ab[123][123][123]','ab1 ab2 ab3 ab4 ab123'))
结果:
['ab123']
21.
print(re.findall('ab{3}','ab1 abbbbbbbb2 abbbbb3 ab4 ab122'))#限制b的长度 结果:['abbb', 'abbb']
print(re.findall('ab{0,}','a123123123 ab1 abbb123 abbbbbbb123 abbbbbtb'))#b 0个到无穷大 结果:['a', 'ab', 'abbb', 'abbbbbbb', 'abbbbb']
print(re.findall('ab{2,}','a123123123 ab1 abb123 abbbb123 abbbbbt')) 结果:['abb', 'abbbb', 'abbbbb']
22.
print(re.findall('a.*c','a2c abc aec a1c'))#贪婪方式匹配a和c之间除了换行任何字符 结果:['a2c abc aec a1c'] 23.
print(re.findall('a.*?c','ac abc aec a1c'))#a到c之间任意字符 结果:['ac', 'abc', 'aec', 'a1c'] print(re.findall('a.*?c','ac abc a111111111c a\nc a1c',re.S))#\n需要转意 结果:['ac', 'abc', 'a111111111c', 'a\nc', 'a1c']
24.()分组 #(y|ies)找到y和ies结尾的
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company')) 结果:['companies', 'company'print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab
结果:['ab'] print(re.findall('(?:ab)+123','ababab123'))
结果:['ababab123']
print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义 结果:['a\\c']
print(re.findall('a\\\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义 print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c']
re.search:会扫描整个字符串,不会从头开始,找到第一个匹配的结果就会返回
print(re.match('a','aleaa make love').group())
content='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'res=re.search('Hello.*?(\d+).*?Demo',content) #print(res.group(1)) #输出结果为
res=re.findall('a','aadddacccaa')#findall找到所以符合条件的结果 for i in res: print(i)
print(re.split('[ab]','abcd'))
#re.sub:字符串替换import recontent='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'# content=re.sub('\d+','',content)# print(content)
print(re.sub('^a','A','alex make love'))#以a为开头的替换
print(re.sub('a','A','alex make love'))#替换所以a
print(re.sub('^(\w+)(\s)(\w+)(\s)(\w+)',r'\5\2\3\4\1','alex make love'))#love make alex # print(re.sub('^(\w+)(\s+)(\w+)(\s+)(\w+)',r'\5','alex make love')) # print(re.sub('^(\w+)(\W+)(\w+)(\W+)(\w+)',r'\5\2\3\4\1','alex " \ + = make ----/== love'))#
跟findall区别就是search找到companies就返回就不会再找了只返回一个 # print(re.search('companies|company','my company is already done,all companies will be done').group())
#用\1取得第一个括号的内容#用法:将123与456换位置# import re# content='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'## # content=re.sub('(Extra.*?)(\d+)(\s)(\d+)(.*?strings)',r'\1\4\3\2\5',content)# content=re.sub('(\d+)(\s)(\d+)',r'\3\2\1',content)# print(content)
# print(re.findall(r'\-?\d+\.\d+|(\-?\d+)',"1-2*(60+(-40.35/5.3+1.2)-(-4*3))")) s=''' 你好啊 alex 大傻逼 alex的邮箱是3781231123@qq.com 010-18211413111 378533872 ''' print(re.findall(r"[1-9][0-9]{4,}",s))