【发布时间】:2021-10-02 14:31:35
【问题描述】:
我在 SO 的黑暗中度过了 5 个小时,所以我将这个问题作为最后的手段发布,我真诚地希望有人能在这里指出我正确的方向:
场景:
-
我有一些来自多种语言的 Google 调查的 .csv 文件(UTF-8 CSV:使用 file -I 命令验证)。输出:
download.csv: application/csv; charset=utf-8 -
我有一个“字典”文件,其中包含问题和答案的翻译(一列是 $language,另一列是英语)。
-
Google 的数据中有很多特殊类型的字符(变音符号和法语重音字母等),因为法语、德语、荷兰语
-
我构建的字典文件可以很好地读取为 UTF-8,包括特殊字符,并准确地创建查找/替换键(使用打印命令验证)
问题在于 Google 文件只能使用 Python 中的 csv.read 函数正确读取(保持正确的字符)。但是,该函数没有 .replace,所以我可以做一个或另一个:
- 读入源文件,不做任何替换,得到一个完美的副本(不是我需要的)
- 将 csv 文件/行转换为文件输入/字符串(请记住,UTF-8 仍然是),并得到一个完全颠簸的输出文件,缺少替换,因为数据以某种方式“松散”了 csv 读取和字符串之间的编码?
代码(此处)最接近工作,除了 csv.reader 上没有 .replace 方法:
import csv
#set source, output
source = 'fr_to_trans.csv'
output = 'fr_translated.csv'
dictionary = 'frtrans.csv'
find = []
replace = []
# build the dictionary itself:
with open(dictionary, encoding='utf-8') as dict_file:
for line in dict_file:
#print(line)
temp_split = []
temp_split = line.split(',')
if "!!" in temp_split[0] :
temp_split[0] = temp_split[0].replace("!!", ",")
find.append(temp_split[0])
if "!!" in temp_split[1] :
temp_split[1] = temp_split[1].replace("!!", ",")
replace.append(temp_split [1])
#print(len(find))
#print(len(replace))
#set loop counters
check_each = len(find)
# Read in the file to parse
with open(source, 'r', encoding='utf-8') as s_file, open(output, 'w', encoding='utf-8') as t_file :
output_writer = csv.writer(t_file)
for row in csv.reader(s_file):
the_row = row
print(the_row) #THIS RETURNS THE CORRECT, FORMATTED, UTF-8 DATA
i = 0
# find and replace everything in the find array with it's value in the replace array
while i < check_each :
print(find[i])
print(replace[i])
# THIS LINE DOES NOT WORK:
the_row = the_row.replace(find[i], replace[i])
i = i + 1
output_writer.writerow(the_row)
我不得不假设即使 Google 文件说它们是 UTF-8,它们也是一种特殊的“Google 品牌 UTF-8”或类似的废话。使用 csv.reader 正确打开文件,但您对此无能为力,这一事实令人愤怒至极。
只是为了澄清我的尝试:
- 将文件视为文本,让 Python 整理编码(失败)
- 将文件视为 UTF-8 文本(失败)
- 以 UTF-8 格式打开文件,替换字符串,并使用 csv.writer 写出(失败)
- 将 the_row 转换为字符串,然后替换,然后用 csv.writer 写出(失败)
- 快速编辑 - 尝试使用字符串的 utf-8-sig - 更好,但输出仍然完全损坏,因为它不是将其读取为 csv,而是字符串
我没试过:
- “逐个单元格”比较,而不是整行(在这渗透到 SO 时进行处理)
- 文件的不同编码(我只能获取 UTF-8 CSV,所以需要某种实用程序?)
如果这些是 ASCII 文本,我会在很久以前就完成了,但是整个“UTF-8 不是但是”的事情让我发疯了。有人对此有任何想法吗?
【问题讨论】:
-
没有“特殊的 Google 品牌 UTF-8”之类的东西,您必须比这更具体。
-
“把文件当成文本,让 Python 整理编码(失败)” 也没有“神奇的文本文件编码检测”这回事。 Python 无法为您解决这个问题。无论是通过 HTTP 标头还是通过字节顺序标记都明确声明了编码,或者您需要在打开文本文件之前知道它。
-
您可能希望添加文件的相关示例,以 a) 显示文件结构,并且 b) 可重现地演示问题。总体而言,这并不像您的问题中看起来那么难,但是您混淆了一些概念。
-
我希望可以,但它们包含大量 PII/品牌信息/专有信息,我无法共享源数据文件。我认为最大的问题是,与大多数查找/替换练习不同,我想有效地替换工作表的整个单元格,例如通过匹配法语中的完整短语,然后用英文翻译替换它的每一个出现。当未保留特殊字符的文件编码并且匹配失败/输出因特殊字符而损坏时,就会出现此问题。为什么以 UTF-8 和原生 CSV 格式读取文件是不同的,这是症结所在。
-
以相同格式发布虚假数据。我们不需要很多行。