正则表达式
正则表达式:(http://tool.chinaz.com/regex/?qq-pf-to=pcqq.group)
什么是正则表达式?
(1)一种匹配字符串的规则
(2)input 一串数据
1)是不是QQ号:全数字 5位以上 12位一下,第一位不是零 [1-9](\d{5,11})
2)是不是身份证号 :18位/15位 第一位不是零 18位的最后一位可能是x或者数字 \d{17}[\d|x]|\d{15}
(3)有一个文件:要你把这个文件中所有的手机号都摘取出来
正则表达式能做什么?
(1)可以制定一个规则
1.来确认字符串是否符合规则(判断)
2.从大字段的字符串中找到符合规则的(筛选)
(2)程序领域
1.登录注册页的表单验证,web开发,要求简单的语法
2.爬虫:把网页下载下俩,从里面提取一些信息,找到我要的所有信息,进行数据分析
3.自动化开发,日志分析
注:正则表达式是一种独立的语法,和python没关系,但python可以操作正则.
字符组[]:在一个字符的位置上能出现的内容
[1bc] 表示一个范围
[0-9][a-z][A-Z] 匹配三个字符(数字,小写字母,大写字母)
[abc0-9] 匹配一个字符(小写字母+数字)
[0-9a-zA-Z] 匹配一个字符(数字+小写字母+大写字母)
\d == [0-9] 也表示匹配一个字符,匹配的是一个数字
\w == [0-9a-zA-Z_] 表示匹配数字字母下划线
\s == [\n \t] 表示匹配回车,空格,制表符(tab)
\n 匹配回车
\t 匹配制表符
\D 表示匹配非数字
\W 表示匹配非数字字母下划线
\S 表示匹配非空白
[\d\D] [\w\W] [\s\S] 表示匹配所有
从头开始去匹配字符串,能匹配到多少个符合规则的就是多少条结果
特殊的用法和现象:
?的使用:
1.在量词的后面跟了一个 ? 取消贪婪匹配 非贪婪(惰性)模式
2.最常用 .*?x 匹配任意字符直到找到一个x
3. .{1,3}? 惰性匹配 回溯算法
在python中使用正则表达式:
转义符:
python中的转义符 \:
'\n' \转义符 赋予这个n一个特殊的意义 表示一个换行符
正则表达式中的转义 :
1.'\(' 表示匹配小括号
2.[()+*?/$.] 在字符组中一些特殊的字符会现出原形
3.所有的 \w \d \s(\n,\t, ) \W \D \S都表示它原本的意义
4.[-]只有写在字符组的首位的时候表示普通的减号,写在其他位置的时候表示范围[1-9],如果就是想匹配减号 [1\-9]
注:在测试的工具中,如果带了\,你又担心它会出现转义的情况,不管三七二十一,在测试工具里测好了的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#1.findall : import re ret = re.findall('\d+','19874ashfk01248') print(ret) # 参数 返回值类型:列表 返回值个数:1 返回值内容:所有匹配上的项 #2.search : ret1 = re.search('\d+','@$sdsdsd23432dsfs') print(ret1) #<_sre.SRE_Match object; span=(2, 7), match='19874'> 如果没有匹配上就是None if ret2: print(ret2.group()) # 返回的对象通过group来获取匹配到的第一个结果 #3.match : ret2 = re.match('\d+','214124dshdusiho12j43io2') print(ret2) #<_sre.SRE_Match object; span=(0, 6), match='214124'> #4.sub(替换 replace) print('replace789,24utdeedeeeeshf'.replace('e','H',3)) #rHplacH789,24utdHedeeeeshf ret3 = re.sub('\d+','H','replace789nbc2xcz392zx') print(ret3) #replaceHnbcHxczHzx #5.subn ret4 = re.subn('\d+','H','replace789nbc2xcz392zx') print(ret4) #('replaceHnbcHxczHzx', 3) #6.split(切割) print('alex|83|'.split('|')) # ['alex', '83', ''] ret5 = re.split('\d+','alex83egon20taibai40') print(ret5) #['alex', 'egon', 'taibai', ''] #进阶方法 - 爬虫\自动化开发 #7.compile(时间效率) re.findall('-0\.\d+|-[1-9]+(\.\d+)?','alex83egon20taibai40') #--> python解释器能理解的代码 --> 执行代码 ret6 = re.compile('-0\.\d+|-[1-9]\d+(\.\d+)?') res = ret6.search('alex83egon-20taibai-40') print(res.group()) # 节省时间 : 只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率 #8.finditer(空间效率) print(re.findall('\d','sjkhkdy982ufejwsh02yu93jfpwcmc')) re7t = re.finditer('\d','sjkhkdy982ufejwsh02yu93jfpwcmc') for r in ret7: print(r.group())
python中的正则表达式:
findall:优先显示分组中的内容,要想取消分组优先.(?正则表达式)
split:遇到分组会保留分组中被切掉的内容
search:如果search中有分组的话,通过group(n)可以拿到group中匹配的内容
正则表达式进阶;
分组命名:
(?P<name>正则表达式):表示给分组起名字
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re ret = re.search("<(?P<name>\w+)>\w+</(?P=name)>","<h1>hello</h1>") print(ret.group('name')) #结果 :h1 print(ret.group()) #结果 :<h1>hello</h1>
(?P=name)表示使用这个分组,这里匹配到的内容应该和分组里的内容完全相同
通过索引使用分组;
\1 表示使用第一组,匹配到的内容必须和第一组的内容完全相同
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#随机 : 在某个范围内取到每一个值的概率是相同的 #随机小数: import random print(random.random()) # 0-1之内的随机小数 print(random.uniform(1,5)) # 任意范围之内的随机小数 #随机整数: print(random.randint(1,2)) # [1,2] 包含2在内的范围内随机取整数 print(random.randrange(1,2)) # [1,2)不包含2在内的范围内随机取整数 print(random.randrange(1,10,2)) # [1,10)不包含10在内的范围内随机取奇数 #随机抽取: #随机抽取一个值 lst = [1,2,3,'aaa',('wahaha','qqxing')] ret = random.choice(lst) print(ret) #随机抽取多个值 ret2 = random.sample(lst,2) print(ret2) #打乱顺序,在原列表的基础上做乱序 #生成验证码: import random def func(n = 6): code = '' for i in range(n): a = random.randint(0, 9) b = chr(random.randint(97, 122)) c = chr(random.randint(65, 90)) d = random.choice([a, b, c]) code = ''.join([code, str(d)]) return code a = func() print(a)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time #1.时间戳时间,格林威治时间,float数据类型 给机器用的 print(time.time()) # 时间戳时间 #2.结构化时间,时间对象 (上下两种格式的中间状态)时间对象,能够通过.属性名来获取对象中的值 time_obj = time.localtime() # 对象数据结构的 print(time_obj) print(time_obj.tm_year) print(time_obj.tm_mday) #3.格式化时间,字符串时间,str数据类型,给人看的,可以根据你需要的格式来显示时间 print(time.strftime('%Y-%m-%d')) # 格式化时间 str format time
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import sys sys.argv #命令行参数List,第一个元素是程序本身路径 sys.exit(n) #退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version #获取Python解释程序的版本信息 sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform #返回操作系统平台名称
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
os.getcwd() #获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") #改变当前脚本工作目录;相当于shell下cd os.curdir #返回当前目录: ('.') os.pardir #获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') #可生成多层递归目录 os.removedirs('dirname1') #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') #生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.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.popen("bash command).read() #运行shell命令,获取执行结果 os.environ #获取系统环境变量 #os.path 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不存在,返回False os.path.isabs(path) #如果path是绝对路径,返回True os.path.isfile(path) #如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) #如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) #返回path所指向的文件或者目录的最后访问时间 os.path.getmtime(path) #返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) #返回path的大小
序列化模块(import json):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串 print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"} #注意,json转换完的字符串类型的字典中的字符串是由""表示的 dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典 #注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示 print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}] str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型 print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] list_dic2 = json.loads(str_dic) print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json f = open('json_file','w') dic = {'k1':'v1','k2':'v2','k3':'v3'} json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() f = open('json_file') dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 f.close() print(type(dic2),dic2)