引言
Python关于文件读写的知识讲了很多,但是今天在用的时候发现,关于清空的命令有一点需要注意的。
问题起源
写博文想褥羊毛,于是就在博文后面加上了领取支付宝红包的二维码。说加就加了。还好博文不多,就全部手动加上去了。
转眼一看,WTF,感觉没写清楚,而且也有点问题,就想把原来写的替换成别的。又不想手动搞,本着能编程解决的,绝不手动,说干就干。
说起来替换文字思路也简单:
- 打开文件
- 读取全文内容
- 找到需要替换的内容
- 用新的内容替换旧的内容
- 写入原文件
看着简单,实际上里面有很多小细节,我觉得值得讨论。
打开文件
打开文件,直接用open
当然好,但是还要close
,所以一般都是用with open() as f:
这种形式,这样就不用手动关闭了。
open
的时候记得注意文件的编码,我的博文都是utf8
的编码,所以要加上open(encoding=='utf8')
这个选项。
读取全文内容
读取全文内容就是简简单单的f.read()
了。
找到需要替换的内容
这个地方,有两种思路,一种是直接把原文中的所有内容全部存到一个字符串变量里面,但是如果太长或者包括换行符,就很难看了。所以我觉得可以是用正则表达式。
替换
你read()
之后,会返回一串字符串,然后字符串本身有一个replace()
方法,直接替换成新的内容就好。
replace()
并不改变原来的字符串,而是返回一个替换后的新的字符串。
写入原文件
这一步最令我鸟大。因为在read
之后,文件指针会跑到末尾,再往里面写会变成追加。
我就想着先清除里面的内容,用的是f.truncate()
这样一个方法,但是竟然没有效果。
后来发现,只有当文件指针在最开头的时候,这个清空函数才有效果,只要你读取过了,哪怕是一个字符,文件指针就不在开头了,这个函数都不起效。
所以要先用f.seek(0)
,将文件指针移到开头去。
伪代码
说了那么多有的没的,上代码才是真。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import re
file_path = r'文件绝对路径'
with open(file_path, 'r+', encoding='utf8') as f:
text = f.read()
# 正则表达式找到要替换的全部内容
pattern1 = re.compile(r"替换内容开头[\s\S]*替换内容结尾")
find_text = pattern1.findall(text)
if find_text == []:
print('Warning: 不存在替换!')
else:
find_text = find_text[0]
replace_text = r'替换后的内容'
text = text.replace(find_text, replace_text)
f.seek(0, 0) #这一步很关键
f.truncate()
f.write(text)