2

我正在尝试解析(和转义)以Windows-1251字符编码存储的 CSV 文件的行。使用这个出色的答案来处理这种编码,我最终用这一行来测试输出,出于某种原因,这可行:

print(row[0]+','+row[1])

输出:

Тяжелый Уборщик Обязанности,1 литр

虽然这条线不起作用:

print("{0},{1}".format(*row))

输出此错误:

Name,Variant

Traceback (most recent call last):
  File "Russian.py", line 26, in <module>
    print("{0},{1}".format(*row))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)

以下是 CSV 的前 2 行:

Name,Variant
Тяжелый Уборщик Обязанности,1 литр

如果有帮助,这里是 Russian.py 的完整来源:

import csv
import cgi
from chardet.universaldetector import UniversalDetector
chardet_detector = UniversalDetector()

def charset_detect(f, chunk_size=4096):
    global chardet_detector
    chardet_detector.reset()
    while 1:
        chunk = f.read(chunk_size)
        if not chunk: break
        chardet_detector.feed(chunk)
        if chardet_detector.done: break
    chardet_detector.close()
    return chardet_detector.result

with open('Russian.csv') as csv_file:
    cd_result = charset_detect(csv_file)
    encoding = cd_result['encoding']
    csv_file.seek(0)
    csv_reader = csv.reader(csv_file)
    for bytes_row in csv_reader:
        row = [x.decode(encoding) for x in bytes_row]
        if len(row) >= 6:
            #print(row[0]+','+row[1])
            print("{0},{1}".format(*row))
4

3 回答 3

6

您列表中的字符串可能已经是 unicode,因此您没有遇到问题。

print(row[0]+','+row[1])
Тяжелый Уборщик Обязанности,1 литр

但是在这里我们试图将 unicode 添加到普通字符串中!这就是为什么你得到UnicodeEncodeError.

print("{0},{1}".format(*row))

所以只需将其更改为:

print(u"{0}, {1}".format(*row))
于 2015-05-26T21:21:37.063 回答
3

您正在使用str.format()which隐式转换unicode()为。str()它必须这样做才能将值插入到提供的模板中。

改用unicode.format()

print(u"{0},{1}".format(*row))

注意u格式文字之前的。unicode.format()必须对输入进行解码 str以适应生成的 Unicode 输出。

另一方面,连接可以隐式解码以产生最终的unicode()对象结果。如果您的','值包含非 ASCII 字节,那么隐式解码也会失败。

故事的寓意:在处理文本时,在整个代码中使用 Unicode 字符串文字。

于 2015-05-26T21:23:59.913 回答
0

操作数在字符串和字符串+之间工作正常。另一方面,不接受字符串作为参数。unicodestrstr.formatunicode

因此,您可以简单地将有问题的行替换为以下内容:

print(u"{0},{1}".format(*row))

这应该够了吧。

于 2015-05-26T21:22:29.997 回答