在正则表达式中帮助我们表示匹配的内容的符号都是正则中的原字符
字符组:[] 一个中括号只表示一个字符位置 # [abc] [0-9] [a-zA-Z]
非字符组:[^]
\d 匹配一位任意数字
\w 匹配数字、字母、下划线
\s 匹配所有空白(包括空格( )、tab(\t)、enter(\n))
\W 匹配非数字、字母、下划线
\D 非数字
\S 非空白
\b 匹配单词结尾字符 #
[\d\D] [\w\W] [\s\S] 表示匹配所有
. 表示匹配除换行符之外的所有
[^\d] # 匹配所有非数字
^ 开始匹配符
$ 终止匹配符
| 或(优先匹配符号左边,只能匹配一边)
\ 转义符
() 约束|描述范围作用域
在量词允许的情况下,尽量多的匹配
.*x 表示匹配任意字符,任意多次数,遇到最后一个x才停下来
eg: \d{3, }6 此处结尾会是最后一个匹配到的6
\ 取消字符特殊意义 [.] 匹配.符号
在python中操作正则表达式
re.findall(‘正则表达式’, 需要匹配的字符串)
re.search(‘正则表达式’, 需要匹配的字符串)
re.findall() 分组优先使用原因和好处
import re
ret = re.findall('<\w+>(\w+)\w+>', 'bafhgakjkf54sf5dsg452as4fds
')
print(ret) # ['bafhgakjkf54sf5dsg452as4fds']
ret2 = re.search('<\w+>(\w+)\w+>', 'bafhgakjkf54sf5dsg452as4fds
')
print(ret2) #
print(ret2.group()) # bafhgakjkf54sf5dsg452as4fds
print(ret2.group(0)) # bafhgakjkf54sf5dsg452as4fds
print(ret2.group(1)) # bafhgakjkf54sf5dsg452as4fds
re.split(正则表达式, 被切割字符)
根据正则表达式切割某个字符串
ret = re.split('\d+','alex222wusir')
ret = re.split('\d(\d)\d','alex123wusir')
print(ret)
re.sub(正则表达式, 替换字符, 被替换字符串)
根据正则表达式替换字符串的匹配字符
返回替换后字符串
ret = re.sub('\d+','H','alex123wusir456',1)
print(ret)
re.subn(正则表达式, 替换字符, 被替换字符串)
根据正则表达式替换字符串的匹配字符
返回元组(替换后字符串, 替换次数)
ret = re.subn('\d+','H','alex123wusir456')
print(ret)
re.match(正则表达式, 字符串)
相当于search,但是规定必须开头是什么
match和search
match规定这个字符串必须是什么样
search用于字符串是不是含有满足条件的子字符串
ret = re.match('\d+','123eva456taibai')
print(ret.group())
ret = re.search('^\d+','123eva456taibai')
print(ret.group())
re.compile(正则表达式)
同一个正则表达式要被使用多次
节省了多次解析同一个正则表达式的时间
ret = re.compile('\d+')
res1 = ret.search('alex37176')
res2 = ret.findall('alex37176')
print(res1)
print(res2)
re.finditer()
相当于findall(),但是返回一个迭代器
节省空间
ret = re.finditer('\d+','agks1ak018093')
for i in ret:
print(i.group())
先compile,再finditer
既节省时间又节省空间
ret= re.compile('\d+')
res = ret.finditer('agks1ak018as093')
for r in res:
print(r.group())
补充知识
list尽量不用insert()和pop(n) 节省空间
程序要求
功能
性能
时间:
空间:
用户体验
分组命名规则:
ret = re.search('\d(\d)\d(\w+?)(\d)(\w)\d(\d)\d(?P\w+?)(\d)(\w)\d(\d)\d(?P\w+?)(\d)(\w)' ,
'123abc45678agsf_123abc45678agsf123abc45678agsf')
print(ret.group('name1'))
print(ret.group('name2'))
分组命名引用
import re
exp= 'akd7008&(&*)hgdwuih008&(&*)hgdwuih'
ret= re.search('<(?P\w+)>.*?(?P=tag)>' ,exp)
print(ret)
# exp= 'akd7008&(&*)hgdwuih 008&(&*)hgdwuih'
# ret= re.search(r'<(\w+)>.*?\1>',exp)
# ret= re.search('<(\w+)>.*?\\1>',exp)
# print(ret)
# ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
# print(ret)
# ret = ['1', '2', '60', '', '5', '4', '3','','']
# ret.remove('')
# print(ret)
# ret = filter(lambda n:n,ret)
# print(list(ret))
高级的文件、文件夹、压缩包处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
import shutil
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
shutil.copyfile(src, dst)
拷贝文件
shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
shutil.copy(src, dst)
拷贝文件和权限
import shutil
shutil.copy('f1.log', 'f2.log')
shutil.copy2(src, dst)
拷贝文件和状态信息
import shutil
shutil.copy2('f1.log', 'f2.log')
shutil.ignore_patterns(\*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
import shutil
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
import shutil
shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
'''
通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
'''
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
import shutil
shutil.rmtree('folder1')
shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名
import shutil
shutil.move('folder1', 'folder3')
total, used, free = shutil.disk_usage("c:\\")
print("当前磁盘共: %iGB, 已使用: %iGB, 剩余: %iGB"%(total / 1073741824, used / 1073741824, free / 1073741824))
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
#将 /data 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
#将 /data下的文件打包放置 /tmp/目录
import shutil
ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()
# 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall(path='.')
z.close()
# 压缩
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()
import logging
# 输出内容是有等级的 : 默认处理warning级别以上的所有信息
logging.debug('debug message') # 调试
logging.info('info message') # 信息
logging.warning('warning message') # 警告
logging.error('error message') # 错误
logging.critical('critical message') # 批判性的
排错处理
# 排错处理实例
def cal_mul(exp):
exp = 4*6
logging.debug('4*6 = 24')
return 24
def cal_div():
pass
def cal_add():
pass
def cal_sub(exp):
exp = 3-24
logging.debug('cal_sub :3-24 = 21')
return 21
def cal_inner_bracket(exp2):
exp2 = 3-4*6
ret = cal_mul(4*6)
exp2 = 3-24
ret = cal_sub(3-24)
logging.debug('3-4*6 = -21')
return -21
def main(exp):
exp =(1+2*(3-4*6))/5
ret = cal_inner_bracket(3-4*6)
return ret
logging.basicConfig(level=logging.DEBUG)
ret = main('(1+2*(3-4))/5')
print(ret)
数据分析 —— 记录到日志
# 记录日志
# 输出到屏幕
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
)
logging.warning('warning message test2')
logging.error('error message test2')
logging.critical('critical message test2')
#
# 输出到文件,并且设置信息的等级
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
filename='tmp.log',
level= logging.DEBUG
)
# logging.debug('debug 信息错误 test2')
# logging.info('warning 信息错误 test2')
# logging.warning('warning message test2')
# logging.error('error message test2')
# logging.critical('critical message test2')
# 同时向文件和屏幕上输出 和 解决文件乱码
import logging
fh = logging.FileHandler('tmp.log', encoding='utf-8')
# fh2 = logging.FileHandler('tmp2.log',encoding='utf-8')
sh = logging.StreamHandler()
logging.basicConfig(
format = '%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',
datefmt = '%Y-%m-%d %H:%M:%S %p',
level = logging.DEBUG,
# handlers = [fh,sh,fh2]
handlers = [sh, fh],
)
logging.debug('debug 信息错误 test2')
logging.info('warning 信息错误 test2')
logging.warning('warning message test2')
logging.error('error message test2')
logging.critical('critical message test2')
# 做日志的切分
import logging
import time
from logging import handlers
sh = logging.StreamHandler()
rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5) # 按照大小做切割
fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8')
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level= logging.DEBUG,
# handlers=[fh,sh,fh2]
handlers=[fh,rh,sh]
)
for i in range(1,100000):
time.sleep(1)
logging.error('KeyboardInterrupt error %s'%str(i))
参考原文链接1
参考原文链接2