Python文件读写之内容替换

引言

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
16
import 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)