一个Python脚本纠错的求助

如题。需要一个脚本完成以下工作:
text_file.txt中搜索关键字==,并在第n次命中时将其替换为replacements_file.txt中第n行的内容(换个说法,就是将replacements_file.txt按每行一个的方式生成替换表并顺次替换命中的关键字),最后将完成替换的文本输出至output_file.txt中。已知关键字出现次数与替换表项目数相等。
调戏了Monica(GPT3.5)一段时间后,给出了如下脚本:

import codecs

with codecs.open('text_file.txt', 'r', encoding='utf-8') as file:
    text = file.read()

with codecs.open('replacements_file.txt', 'r', encoding='utf-8') as file:
    replacements = file.read().splitlines()

keywords = ["=="]
replaced_text = text

for i in range(len(keywords)):
    count = 0
    replaced_text = replaced_text.replace(keywords[i], lambda match: replacements[i] if count == match.start() else match.group(0), -1)
    count += len(replacements[i])

with codecs.open('output_file.txt', 'w', encoding='utf-8') as file:
    file.write(str(replaced_text))

运行时报错:

Traceback (most recent call last):
  File "work.py", line 14, in <module>
    replaced_text = replaced_text.replace(keywords[i], lambda match: replacements[i] if count == match.start() else match.group(0), -1)
TypeError: coercing to Unicode: need string or buffer, function found

想请各位看看,具体该如何修正?

我记得python的字符串替换方法是这样的
https://python-reference.readthedocs.io/en/latest/docs/str/replace.html

这里的第二个参数传入的是一个匿名函数不是字符串

1 个赞

gpt 搞混 str.replace 和 re.replace 了吧

1 个赞

试试看这个,用记事本写的格式不一定对。
with open(‘text_file.txt’, ‘r’, encoding=‘utf-8’) as file:
text = file.read()

with open(‘replacements_file.txt’, ‘r’, encoding=‘utf-8’) as file:
replacements = file.read().splitlines()

keywords = “==”
replace_time = text.count(keywords)
result_text = text

for i in range(replace_time):
result_text = result_text.replace(keywords, replacements[i], 1)

with open(‘output_file.txt’, ‘w’, encoding=‘utf-8’) as file:
file.write(result_text)

1 个赞

感谢!这个脚本工作正常,完全没有问题(当然改掉了中文引号、以及鬼知道为什么总之我的奇怪环境让我不得不引入了codecs模块)。再次感谢!


以及我把最后用的脚本放在这里,以便将来的自己以及其他有需要的朋友们开箱即用。

import codecs

with codecs.open('text_file.txt', 'r', encoding='utf-8') as file:
    text = file.read()

with codecs.open('replacements_file.txt', 'r', encoding='utf-8') as file:
    replacements = file.read().splitlines()

keywords = "=="
replace_time = text.count(keywords)
result_text = text

for i in range(replace_time):
    result_text = result_text.replace(keywords, replacements[i], 1)

with codecs.open('output_file.txt', 'w', encoding='utf-8') as file:
    file.write(result_text)

这个 gpt 真奇怪,一般用open()函数就行了,不需要codecs.open(),如果要兼容 py2.x 的话,一般也是用io.open()也不是这个codecs.open()啊。

!我甚至直到今天发现你的帖子才知道py3版本可以直接用open……每次都是io.open(),果然学的时候被过时教程荼毒不浅……

啊,这个嘛,因为我要对付的文档里是UTF-8的,导致一开始整出来的结果乱码,问它就让加了encoding='utf-8',又报错,于是就又让加个codecs模块……

# coding=utf-8 这样吧,你漏井号了?

还有就是有没有bom,utf8和utf8bom经常给我整出来报错

1 个赞

你看 Python open()函数的文档,里面有讲了:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

如果你担心报错,那么传一个errors参数就行了。open(..., errors="ignore"),碰到非 utf-8 的文件就不会报错了。

1 个赞

#coding=utf-8 是用于描述源代码的编码的。在 Python 3.x 里面默认都是 utf-8,而且推荐开发者都使用 utf-8,所以这一行可以省掉了。这个声明和你要打开的文件的编码是没有关系的。

如果确实要处理比较复杂的文件编码问题,建议使用chardet这个模块。它可以探测要打开的文件的编码,然后你们在open()函数里面传入编码就能打开了。

Windows 弄了一个 utf-8 的 bom 比较蠢。有时候只能自己稍微处理一下了。一般大家自己使用的话,建议统一用没有 bom 的 utf-8.

唔,可能是因为我天天用utf8bom的csv吧……我的excel打开utf8乱码,只有bom不乱码,并且有时候临时用文本编辑器打开py文件,utf8也可能乱码……所以无论是pandas.readcsv()还是io.open()还是原始代码啥的我都会显式声明以防万一……

那如果是这样的话,以后你应该统一使用utf-8-sig编码来打开文件,而不是声明utf-8,这样写:

with open(r"c:\test.csv", encoding="utf-8-sig", errors="ignore") as f:
    print(f.read())  # 处理文件

如果只用utf-8的话,读 BOM 头的时候仍然有一定的可能性会出错。

utf-8-sig这个编码能够处理普通的utf-8文件。碰到没有 BOM 头也不会出错。

我都是直接utf8硬读,看一下前100字符是否出现锟斤拷以及黑方框,否则更换为utf8bom,这样子就没事了