【问题标题】:Force Python to Use 4 digit Unicode Encoding (CSV Writer)强制 Python 使用 4 位 Unicode 编码(CSV Writer)
【发布时间】:2017-03-13 19:24:12
【问题描述】:

我在 python 3 中使用 CSV 模块。我打开我的输出文件

open(file_name, 'w', encoding="ascii", errors="backslashreplace")

然后将 Unicode 字符串写入文件。 Unicode 字符被替换为十六进制表示,例如:

f\xfcr

不幸的是,我的解析器 (JavaScript) 不理解这种表示,并且想要类似

f\u00FCr

代替(4 位表示)。是否有一些聪明的方法来实现这一点,还是我必须重新打开文件,找到所有出现的地方并自己更改它们?

澄清:我不想使用 utf-8 编码,因为 JavaScript 解析器不理解它。我需要转义 Unicode 字符!

【问题讨论】:

  • 我认为您正在寻找“unicode-escape”编码。
  • 不会将encoding="ascii" 更改为encoding="utf-8" 来解决问题吗?
  • 不,然后我得到“für”,它使我的 JS 解析器崩溃。我需要 \u 编码。 @PM2Ring CSV 模块如何工作?
  • 不幸的是,“unicode-escape”编码为\u007f\u00ff 范围内的字符生成\x 编码。但是,您可以使用 json.dumps 创建 JavaScript 友好的字符串。它将接受单个字符串,以及字典、列表或元组。例如,import json; print(json.dumps('für')) 打印 "f\u00fcr"
  • ensure_ascii=True是默认的,所以不需要指定

标签: javascript python csv unicode


【解决方案1】:

澄清:我不想使用 utf-8 编码,因为 JavaScript 解析器不理解它。

你不得不处理这样一个愚蠢的解析器,真是太不幸了!它似乎将 CSV 数据视为 JSON 数据,而不是正确处理编码数据。这不是一个标准。

您可以将每个值编码为 JSON,然后去掉引号:

import json, csv

def json_escaped(obj):
    res = json.dumps(obj)
    if res[0] == res[-1] == '"':
        res = res[1:-1]
    return res

with open(file_name, 'w', newline='') as outfile:
    writer = csv.writer(outfile)
    for row in source:
        writer.writerow(map(json_escaped, row))

之所以有效,是因为 JSON(几乎完全)是 Javascript 的超集(two exceptions 在将默认 ensure_ascii 设置保留为 True 时,Python 解析器永远不会生成)。

backslashreplace 无法工作,因为只有从 U+0100 到 U+D7FF 和 U+E000 - U+FFFF 的 Unicode 代码点被编码为 \uhhhh 转义。这些范围之外的代码点要么已经是 ASCII,编码为较短的转义码(\n\xhh 等),要么是更长的转义码(\Uhhhhhhhh 用于超过 U+FFFF 的任何内容)。

另一方面,json 编码器只会生成 \uhhhh 转义码,将 UTF-16 surrogate pairs 用于 U+FFFF 上的代码点。

演示:

>>> import csv
>>> from io import StringIO
>>> data = [3.14, 'Unicode face: \u0669(-\u032e\u032e\u0303\u2022\u0303.', 'Something with a non-BMP emoji: \U0001F47D']
>>> with StringIO() as output:
...     writer = csv.writer(output)
...     writer.writerow(map(json_escaped, data))
...     print(output.getvalue())
...
105
3.14,Unicode face: \u0669(-\u032e\u032e\u0303\u2022\u0303.,Something with a non-BMP emoji: \ud83d\udc7d

因此,生成有效的 CSV,将 ASCII 范围之外的任何内容转换为 \uhhhh 序列。

请注意,换行符也会被编码(到 \n),但如果您的解析器将数据视为 JSON 或 Javascript 文字,那么这应该不是问题。

【讨论】:

    猜你喜欢
    • 2018-10-08
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    相关资源
    最近更新 更多