Python 文件和正则--with文件读取,深浅拷贝,正则表达式
1.with语句
-
open 方式打开文件
#open()方式打开文件的弊端. f = open('1.txt','w') f.write('hello world') f.flush() # f.close() == 不释放资源--其它人无法操作被占用的文件. #-------------发生异常导致没有释放资源--------- # f = open('1.txt','r') # f.write('hello world') # f.flush() # f.close() # 可以释放资源---但是格式复杂---麻烦!!! f = None try: f = open('1.txt','r') f.write('hello world') f.flush() except Exception as e: print('出错误了') finally: if f is not None: f.close() while True: pass
-
with语句操作文件
with open("1.txt",'w') as f: f.write('hello\n') f.write('world\n') f.write('python\n') # f.close() # 使用with语句后.能帮我们自动释放资源. while True: pass
2.深拷贝和浅拷贝
-
浅拷贝
# 语法: 1.导入模块 copy import copy # 不可变类型有: 数字、字符串、元组 # a1 = 123 # b1 = copy.copy(a1) # print(id(a1))#2697886781688 # print(id(b1))#2697886781688 # # b2 = a1 # print(id(a1))#2697886781688 # print(id(b2))#2697886781688 # a2 = 'abc' # b2 = copy.copy(a2) # print(id(a2))#2697886781168 # print(id(b2))#2697886781168 # a3 = (1,2,[3,4]) # b3 = copy.copy(a3) # print(id(a3))#2165171410048 # print(id(b3))#2165171410048 # print(id(a3[2]))#2272505786496 # print(id(b3[2]))#2272505786496 # 可变类型有: 列表、字典、集合 # a4 = [1,2,3] # b4 = copy.copy(a4) # print(id(a4))#2281864200256 # print(id(b4))#2281863566720 # a5 = {"name":"tom","age":20} # b5 = copy.copy(a5) # print(id(a5))#1807425866112 # print(id(b5))#1807425866176 # a6 = {1,2,3} # b6 = copy.copy(a6) # print(id(a6))#2784928707520 # print(id(b6))#2784928707744 a7 = [1,2,[3,4]] b7 = copy.copy(a7) print(id(a7))#2081913886016 print(id(b7))#2081913871360 #如果使用浅拷贝拷贝列表中的可变元素.该元素不会被重新创建对象. print(id(a7[2]))#2153571123328 print(id(b7[2]))#2153571123328 a7[2][0] = 9 print(a7)#[1,2,[9,4]] print(b7)#[1,2,[9,4]]
-
深拷贝
# 语法: 1.导入模块 copy import copy a7 = [1,2,[3,4]] b7 = copy.deepcopy(a7) print(id(a7))#2081913886016 print(id(b7))#2081913871360 #如果使用浅拷贝拷贝列表中的可变元素.该元素不会被重新创建对象. print(id(a7[2]))#2153571123328 print(id(b7[2]))#1720282193472 a7[2][0] = 9 print(a7) print(b7)
3.正则表达式入门
# 需求: 校验密码格式是否合法: 格式:6-10位自然数. #定义函数.去判断密码是否合法. import re def check(pwd): #拦截式判断 if not pwd.isdigit(): print('密码不是纯数字') return if len(pwd)<6: print('密码长度最低6位') return if len(pwd)>10: print('密码长度最高10位') return print('密码合法') if __name__ == '__main__': pwd = input('请输入密码') # check(pwd) res = re.match("^[0-9]{6,10}$",pwd) if res: print('密码合格') else: print('密码不合格')
4.正则匹配单个字符
. 匹配任意1个字符(除了\n)
[] 匹配[ ]中列举的字符
\d 匹配数字,即0-9
\D 匹配非数字,即不是数字
\s 匹配空白,即 空格,tab键
\S 匹配非空白
\w 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字
\W 匹配特殊字符,即非字母、非数字、非汉字
import re # res = re.match(".","\n") res = re.match(".","abc") print(res) # <re.Match object; span=(0, 1), match='a'> print(type(res))#<class 're.Match'> print(res.group())#a res = re.match('.','\nbc') # if res is not None: if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') #匹配指定字符 res = re.match('[abc]','cbc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') # 匹配一个纯数字 # res = re.match('[0-9]','1cbc') res = re.match('\d','cbc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') # 匹配非数字,即不是数字 res = re.match('\D','0cbc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') # 匹配空白,即 空格,tab键 # res = re.match('\s','\tcbc') # res = re.match('\s','\ncbc') res = re.match('\s',' cbc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') # \S 匹配非空白 # res = re.match('\S',' 你好bc') res = re.match('\S','你好bc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') # \w 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字 # res = re.match('\w','你好bc') # res = re.match('\w','_bc') res = re.match('\w','&bc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!') # \W 匹配特殊字符,即非字母、非数字、非汉字 res = re.match('\W\W[abc]','&#fc') if res: print(f'匹配成功:{res.group()}') else: print('匹配失败!')
5.正则匹配多个字符
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次
import re print(re.match('[abc]{3}','abc')) # * 匹配前一个字符出现0次或者无限次,即可有可无 print(re.match('\d*','abc'))#match='' print(re.match('\d*','1abc'))#match='1' print(re.match('\d*','123abc'))#match='123' # + 匹配前一个字符出现1次或者无限次,即至少有1次 print(re.match('\d+','abc'))#None print(re.match('\d+','1abc'))#match='1' print(re.match('\d+','123abc'))#match='123' # ? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 print(re.match('\d?','abc'))#match='' print(re.match('\d?','1abc'))#match='1' print(re.match('\d?','12abc'))#match='1' # {m} 匹配前一个字符出现m次 print(re.match('\d{3}','12abc'))#None print(re.match('\d{3}','123abc'))#match='123' print(re.match('\d{3}','1234bc'))#match='123' # {m,n} 匹配前一个字符出现从m到n次 print(re.match('\d{3,5}','12abc'))#None print(re.match('\d{3,5}','123abc'))#match='123' print(re.match('\d{3,5}','1234abc'))#match='1234' print(re.match('\d{3,5}','12345abc'))#match='12345' print(re.match('\d{3,5}','123456abc'))#match='12345'
6.正则匹配开头和结尾
^ 匹配字符串开头
$ 匹配字符串结尾
# 1.匹配以数字开头的数据 import re print(re.match("^\d.*","6hello"))#match='6hello' print(re.match("^\d[a-z]*","6hello"))#match='6hello' # 2.匹配以数字结尾的数据 print(re.match("\d$","3"))#match='3' print(re.match("\d$","hello3"))#None print(re.match(".*\d$","hello123"))#match='hello123' # 3.匹配以数字开头中间内容不管以数字结尾 print(re.match("^\d.*\d$","6hello8"))#match='6hello8' print(re.match("^\d.*\d$","61238"))#match='61238' print(re.match("^\d.*\d$","68"))#match='68' print(re.match("^\d.*\d$","6 8"))#match='6 8' # 4.特殊语法:[^指定字符]: 取反: 表示除了指定字符都匹配 # 需求: 第一个字符除了aeiou的字符都匹配 print(re.match("[^aeiou]","bcd"))#match='b'> print(re.match("[^aeiou]","123"))#match='1'> print(re.match("[^aeiou]","acd"))#None print(re.match("[^aeiou]","ecd"))#None print(re.match("[^aeiou]","ucd"))#None
7.匹配分组
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P<name>) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串
# 1.需求: 在列表中["apple", "banana", "orange", "pear"],匹配apple和pear import re list_str = ["apple", "banana", "orange", "pear"] for i in list_str: res = re.match("apple|pear",i) #如果res不是None,那就匹配到值了 if res: print(res.group()) else: print(f'匹配失败:{i}') # 2.需求: 匹配出163、126、qq等邮箱 email1 = 'hanbaobao@163.com' email2 = 'hanbaobao@126.com' email3 = 'hanbaobao@qq.cn' res = re.match('\w{8,20}@(163|126|qq)\\.(com|cn)',email3) if res: print(f"匹配成功:{res.group()}") else: print(f'匹配失败!') # 3.需求: 匹配qq:10567这样的数据,提取出来qq文字和qq号码 qq = "qq:10567" res = re.match('(qq):(\d{5})',qq) print(res.group())#qq:10567 print(res.group(1))#qq print(res.group(2))#10567 # print(res.group(3)) IndexError: no such group # 4.需求: 匹配出<html>hh</html> # \num 引用分组num匹配到的字符串 my_html = "<html>hh</html>" res = re.match('<([a-zA-Z]+)>.*</\\1>',my_html) print(res.group()) # 5.需求: 匹配出<html><h1>www.itcast.cn</h1></html> my_html = "<html><h6>www.itcast.cn</h6></html>" res = re.match('<([a-zA-Z]+)><([a-zA-Z0-9]+)>.*</\\2></\\1>',my_html) print(res.group()) # 6.需求: 匹配出<html><h1>www.itcast.cn</h1></html> # (?P<name>) 分组起别名 # (?P=name) 引用别名为name分组匹配到的字符串 my_html = "<html><h6>www.itcast.cn</h6></html>" res = re.match('<(?P<name1>[a-zA-Z]+)><(?P<name2>[a-zA-Z0-9]+)>.*</(?P=name2)></(?P=name1)>',my_html) print(res.group())
-
扩展: re.search() re.findall()
# 查询匹配方式. import re my_str = "见风使舵#美国#国会众议院通过了所谓#中国#不是发展#中国#家#法国#法案" res = re.match('#(美国|中国)#',my_str) print(res) #匹配整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回None res = re.search('#(美国|中国)#',my_str) print(res)# <re.Match object; span=(18, 22), match='#中国#'> #re.findall()函数 -- 从开始到结尾去匹配.能匹配到结束. # 默认正则匹配是贪婪的匹配模式:从开头到结尾.中间不会停留. # *? 寻找到一个符合条件的结果就停下来. 继续往下寻找. # +? 寻找到一个符合条件的结果就停下来. 继续往下寻找. res = re.findall('#.*?#',my_str) print(res)# ['#中国#', '#中国#', '#中国#']