在同一个 json 文件中处理混合字符集

问题描述 投票:0回答:1

鉴于我有以下文件:

{
  "title": {
    "ger": "Komödie"    (utf8, encoded as c3 b6)
  },
  "files": [
    {
      "filename": "Kom�die"   (latin1, encoded as f6)
    }
  ]
}

(如果您尝试复制粘贴,可能看起来会有所不同)

这是由于应用程序错误而发生的,我无法修复生成这些文件的源。

我现在尝试修复文件名字段的字符集,可以有多个。我首先尝试使用 jq (单字段):

value="$(jq '.files[0].filename' <in.txt | iconv -f latin1 -t utf-8)"
jq --arg f "$value" '.files[0].filename = $f' <in.txt

但是 jq 将整个文件解释为 utf-8,这会损坏单个 f6 字符。

我想在python中找到解决方案,但同样,输入在linux中默认解释为utf-8。我尝试使用“ascii”,但这不允许字符 >= 128。

现在,我想我找到了一种方法,但是 json 序列化器转义了所有字符。由于我(故意)使用了错误的字符集,因此转义序列也是垃圾。

#!/usr/bin/python3

import sys
import io
import json

with open('in.txt', encoding='latin1') as fh:
  j = json.load(fh)

for f in j['files']:
  f['filename'] = f['filename'].encode('utf-8').decode('latin1')   # might be wrong, couldn't test

with open('out.txt', 'w', encoding='latin1') as fh:
  json.dump(j, fh)

我该怎么做才能达到预期的结果,一个干净的非转义的 utf-8 json 文件?

python json character-encoding
1个回答
0
投票

到目前为止我发现的解决方法是根本不使用 json。它之所以有效,是因为我知道这些文件的结构非常好,并且我可以通过静态文本模式轻松找到断线(带有文件名的断线):

#!/usr/bin/python3

with open('in.txt', encoding='latin1') as fh:
  lines = fh.readlines()

# change the encoding of all filename: lines and keep everything else
lines = [line.encode('utf-8').decode('latin1') if line.startswith("\t\t\t\"filename\": \"") else line for line in lines]

with open('out.txt', 'w', encoding='latin1') as fh:
    fh.writelines(lines)

输出:

{
  "title": {
    "ger": "Komödie"
  },
  "files": [
    {
      "filename": "Komödie"
    }
  ]
}
© www.soinside.com 2019 - 2024. All rights reserved.