用python中的字符替换所有unicode代码

时间:2017-07-05 13:39:51

标签: python json python-3.x unicode unicode-string

我有一个文本文件,如下所示:

  • 升\ u00f6yt \ u00e4 \ u00e4

但是所有unicode字符都需要替换为相应的字符,并且应该如下所示:

  • löytää

问题是我不想自己替换所有的unicode代码,自动执行此操作的最有效方法是什么? 我的代码现在看起来像这样,但需要进行优化!(代码在Python3中)

import io
input = io.open("input.json", "r", encoding="utf-8")
output = io.open("output.txt", "w", encoding="utf-8")
with input, output:
    # Read input file.
    file = input.read()
    file = file.replace("\\u00e4", "ä")
    # I think last line is the same as line below:
    # file = file .replace("\\u00e4", u"\u00e4")
    file = file.replace("\\u00c4", "Ä")
    file = file.replace("\\u00f6", "ö")
    file = file.replace("\\u00d6", "Ö")
    .
    .
    . 
    # I cannot put all codes in unicode here manually!
    .
    .
    .
    # writing output file
    output.write(file)

1 个答案:

答案 0 :(得分:3)

只需将JSON 解码为JSON ,然后写出新的JSON文档,而不确保数据是否为ASCII安全:

import json

with open("input.json", "r", encoding="utf-8") as input:
    with open("output.txt", "w", encoding="utf-8") as output:
        document = json.load(input)
        json.dump(document, output, ensure_ascii=False)

来自json.dump() documentation

  

如果 ensure_ascii 为true(默认值),则保证输出转义所有传入的非ASCII字符。如果 ensure_ascii 为false,则这些字符将按原样输出。

演示:

>>> import json
>>> print(json.loads(r'"l\u00f6yt\u00e4\u00e4"'))
löytää
>>> print(json.dumps(json.loads(r'"l\u00f6yt\u00e4\u00e4"')))
"l\u00f6yt\u00e4\u00e4"
>>> print(json.dumps(json.loads(r'"l\u00f6yt\u00e4\u00e4"'), ensure_ascii=False))
"löytää"

如果您有非常大的文档, 仍可以逐行文本处理它们,但使用正则表达式进行替换:

import re

unicode_escape = re.compile(
    r'(?<!\\)'
    r'(?:\\u([dD][89abAB][a-fA-F0-9]{2})\\u([dD][c-fC-F][a-fA-F0-9]{2})'
    r'|\\u([a-fA-F0-9]{4}))')
def replace(m):
    return bytes.fromhex(''.join(m.groups(''))).decode('utf-16-be')

with open("input.json", "r", encoding="utf-8") as input:
    with open("output.txt", "w", encoding="utf-8") as output:
        for line in input:
            output.write(unicode_escape.sub(replace, line))

如果您的JSON在字符串中嵌入了JSON文档,或者如果转义序列前面有转义反斜杠,则会失败。