python 正则,os,sys,hashlib模块
简单的小算法
random随机获取数据
import random def getrandata(num): a=[] i=0 while i<num: a.append(random.randint(0,100)) i+=1 return a print(getrandata(10))
例:
[5, 3, 38, 4, 69, 40, 94, 36, 14, 26]
冒泡排序
import getdata def bubbleSort(a): l=len(a)-2 i=0 while i<l: j=l while j>=i: if(a[j+1]<a[j]): a[j],a[j+1]=a[j+1],a[j] j-=1 i+=1 print(a) r = getdata.getrandata(10) print(r) bubbleSort(r)
执行结果:
[80, 69, 92, 0, 53, 45, 38, 61, 45, 38] [0, 38, 38, 45, 45, 53, 61, 69, 80, 92]
解析:每次从最后开始往前滚,邻接元素两两相比,小元素交换到前面,第一轮循环把最小的元素上浮至第一个位置,第二小的元素上浮至第二个位置,依次类推。
插入排序
import getdata def insertSort(arr): for i in range(1,len(arr)): j=i while j>0 and arr[j-1]>arr[i]: j-=1 arr.insert(j,arr[i]) arr.pop(i+1) print(arr) r = getdata.getrandata(10) print(r) insertSort(r)
执行结果:
[84, 43, 95, 2, 77, 44, 83, 40, 49, 85] [2, 40, 43, 44, 49, 77, 83, 84, 85, 95]
解析:每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。
选择排序
import getdata def chooseSort(arr): num = len(arr)-1 for i in range(len(arr)): index = 0 for j in range(num): if arr[index] > arr[j+1]: pass else: index = j+1 middle = arr[num] arr[num] = arr[index] arr[index] = middle num -= 1 print(arr) r = getdata.getrandata(8) print(r) chooseSort(r)
执行结果:
[50, 90, 30, 5, 65, 29, 13, 73] [5, 13, 29, 30, 50, 65, 73, 90]
解析:通过在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,放到排序序列末尾,以此类推。
反射
利用字符串的形式去对象(模块)中操作(寻找/检查/删除/设置)属性。【非官方语言】
反射的四种方法:getattr、delattr、setattr、hasattr
- getattr(obj, name[, default]) : 访问对象的属性。
- hasattr(obj,name) : 检查是否存在一个属性。
- setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
- delattr(obj, name) : 删除属性。
【提示】__import__()方法引用的是字符串形式的模块名。import 模块 == __import__('模块')
def run(inp): try: #inp = input('please input url:') m,f = inp.split('/') try: obj = __import__(m) if hasattr(obj,f): func = getattr(obj,f) func() else: print('404') except ImportError as ee: print(ImportError,':',ee) except Exception as e: print(e) if __name__ == '__main__': run('index/home') run('ab/abb') run('index/ffff') run('ffff/ffff') run('ffff')
执行结果:
index模块下的home函数 ab模块下的abb函数 404 <class 'ImportError'> : No module named 'ffff' not enough values to unpack (expected 2, got 1)
os,sys,hashlib模块
os
1 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 2 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd 3 os.curdir 返回当前目录: ('.') 4 os.pardir 获取当前目录的父目录字符串名:('..') 5 os.makedirs('dirname1/dirname2') 可生成多层递归目录 6 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 7 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname 8 os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 9 os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 10 os.remove() 删除一个文件 11 os.rename("oldname","newname") 重命名文件/目录 12 os.stat('path/filename') 获取文件/目录信息 13 os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" 14 os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" 15 os.pathsep 输出用于分割文件路径的字符串 16 os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' 17 os.system("bash command") 运行shell命令,直接显示 18 os.environ 获取系统环境变量 19 os.path.abspath(path) 返回path规范化的绝对路径 ###常用 20 os.path.split(path) 将path分割成目录和文件名二元组返回 21 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 ##常用 22 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 23 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False 24 os.path.isabs(path) 如果path是绝对路径,返回True 25 os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False 26 os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False 27 os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 ##常用 28 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 29 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
sys
sys.argv #命令行参数List,第一个元素是程序本身路径 sys.modules.keys() #返回所有已经导入的模块列表 sys.exc_info() #获取当前正在处理的异常类,exc_type、exc_value、exc_traceback #当前处理的异常详细信息 sys.exit(n) #退出程序,正常退出时exit(0) sys.hexversion #获取Python解释程序的版本值,16进制格式如:0x020403F0 sys.version #获取Python解释程序的版本信息 sys.maxint #最大的Int值 sys.maxunicode #最大的Unicode值 sys.modules #返回系统导入的模块字段,key是模块名,value是模块 sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform #返回操作系统平台名称 sys.stdout #标准输出 sys.stdin #标准输入 sys.stderr #错误输出
利用sys.stdout实现进度条
def progress_test(): bar_length=20 for percent in range(0, 101): hashes = '■' * int(percent/100.0 * bar_length) spaces = ' ' * (bar_length - len(hashes)) sys.stdout.write("\rPercent: [%s] %d%%"%(hashes + spaces, percent)) sys.stdout.flush() time.sleep(0.1) progress_test()
执行结果:
Percent: [■■■■■■■■■■■■■■■■■■■■] 100%
hashlib
import hashlib def md5_encryption(arg): m = arg.encode("utf-8") # 将传入的参数按utf-8编码 h = hashlib.md5("xxby".encode("utf-8")) # 创建添加自定义key的md5对象 h.update(m) # 生成加密串 print(h.digest()) # 二进制的加密串 print(h.hexdigest()) # 十六进制的加密串 md5_encryption('12345')
执行结果:
b'\x80\xd96_\xca\xceC\x04\x92vl\x10p\xa4_\x98' 80d9365fcace430492766c1070a45f98
re模块
Python 的 re 模块(Regular Expression 正则表达式)提供各种正则表达式的匹配操作,和 Perl 脚本的正则表达式功能类似,使用这一内嵌于 Python 的语言工具,尽管不能满足所有复杂的匹配情况,但足够在绝大多数情况下能够有效地实现对复杂字符串的分析并提取出相关信息。Python 会将正则表达式转化为字节码,利用 C 语言的匹配引擎进行深度优先的匹配。
正则表达式语法
贪婪模式与非贪婪模式
正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。
'*','+'和'*'都是贪婪的,可以在后面加个问号,将策略改为非贪婪,只匹配尽量少的RE。
例1:
>>> re.findall(r"a(\d+?)","a23b") # 非贪婪模式 ['2'] >>> re.findall(r"a(\d+)","a23b") ['23']
例2:
>>> re.search('<(.*)>', '<H1>title</H1>').group() '<H1>title</H1>' re.search('<(.*?)>', '<H1>title</H1>').group() '<H1>'
注意比较这种情况:
>>> re.findall(r"a(\d+)b","a23b") ['23'] >>> re.findall(r"a(\d+?)b","a23b") #如果前后均有限定条件,则非匹配模式失效 ['23']
[]里特殊的\,-,^
[]:元字符[]表示字符类,在一个字符类中,只有字符^、-、和\有特殊含义。
字符\仍然表示转义,字符-可以定义字符范围,字符^放在前面,表示非。
非常牛b的\
反斜杠后边跟元字符去除特殊功能
反斜杠后边跟普通字符实现特殊功能
引用序号对应的字组所匹配的字符串
re.search(r"(alex)(eric)com\2","alexericcomeric")
>>> re.search(r"(alex)(eric)com\2","alexericcomeric").group() 'alexericcomeric' >>> re.search(r"(alex)(eric)com\1","alexericcomalex").group() 'alexericcomalex'
re模块
re.findall()
findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags]):
re.findall() 以列表形式返回所有匹配的字符串
例:
re.findall(r'\w*oo\w*', text);获取字符串中,包含'oo'的所有单词
import re text = "JGood is a handsome boy,he is handsome and cool,clever,and so on ...." print (re.findall(r'\w*oo\w*',text))
执行结果:
['JGood', 'cool']
re.match()
match(string[, pos[, endpos]]) | re.match(pattern, string[, flags]):
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
例:
import re line = "Cats are smarter than dogs" matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I) if matchObj: print ("matchObj.group() : ", matchObj.group()) print ("matchObj.group(1) : ", matchObj.group(1)) print ("matchObj.group(2) : ", matchObj.group(2)) else: print ("No match!!")
执行结果:
matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats matchObj.group(2) : smarter
一旦匹配成功,就是一个match object 对象,而match object 对象拥有以下方法:
group() 返回被 RE 匹配的字符串
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置
group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。
re.search()
search(string[, pos[, endpos]]) | re.search(pattern, string[, flags]):
re.search 扫描整个字符串并返回第一个成功的匹配。
例:
import re a = "123abc456" r1=re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 r2=re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123 r3=re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc r4=re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456 print(r1) print(r2) print(r3) print(r4)
执行结果:
123abc456 123 abc 456
re.match()和re.search()的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
例:
import re line = "Cats are smarter than dogs"; matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj: print ("match --> matchObj.group() : ", matchObj.group()) else: print ("No match!!") matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj: print ("search --> matchObj.group() : ", matchObj.group()) else: print ("No match!!")
执行结果:
No match!!
search --> matchObj.group() : dogs
re.split()
split(string[, maxsplit]) | re.split(pattern, string[, maxsplit]):
按照能够匹配的子串将string分割后返回列表。maxsplit用于指定最大分割次数,不指定将全部分割。
>>> re.split('\W+', 'test, test, test.') ['test', 'test', 'test', ''] >>> re.split('(\W+)', ' test, test, test.') [' test ', ', ', ' test ', ', ', ' test ', '.', ''] >>> re.split('\W+', ' test, test, test.', 1) [' test ', ' test, test.']
re.sub()
sub(repl, string[, count]) | re.sub(pattern, repl, string[, count]):
re模块提供了re.sub用于替换字符串中的匹配项。
返回的字符串是在字符串中用 RE 最左边不重复的匹配来替换。如果模式没有发现,字符将被没有改变地返回。
可选参数 count 是模式匹配后替换的最大次数;count 必须是非负整数。缺省值是 0 表示替换所有的匹配。
import re phone = "123-456-789 # 这是一个电话号码" # 删除注释 num = re.sub(r'#.*$', "", phone) print ("电话号码 : ", num) # 移除非数字的内容 num = re.sub(r'\D', "", phone) print ("电话号码 : ", num)
执行结果:
电话号码 : 123-456-789
电话号码 : 123456789