首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Facebook数据导出中解码看似格式错误的Unicode指针utf8表示

从Facebook数据导出中解码看似格式错误的Unicode指针utf8表示
EN

Stack Overflow用户
提问于 2020-06-28 21:04:06
回答 1查看 455关注 0票数 2

类似于在这个职位中,是否有一种方法可以解码从下载我的Facebook数据副本返回的一些看似格式错误的UTF-8数据?

看看一个特定的例子,在我的一次聊天中,我有一条只包含表情符号的发送消息。用message_1.json打开vim文件,查看适当的条目,显示文本"\u00f0\u009f\u0092\u008e"。然而,这与我的终端(Mac OSX)的视图不同。

代码语言:javascript
复制
$ jq '.messages[0].content' message_1.json
"ð"  # stackoverflow seems to be truncating this string, there are 3 extra chars which show as spaces
$ jq '.messages[0].content' message_1.json > utf
$ cat utf
"ð"
$ od -h utf
0000000      c322    c2b0    c29f    c292    228e    000a
0000013
$ wc utf
       1       1      11 utf

这也不同于将表情符号直接粘贴到文件中的输出。

代码语言:javascript
复制
$ echo '' > gem.txt
$ cat gem.txt

$ od -h gem.txt
0000000      9ff0    8e92    000a
0000005
$ wc gem.txt
       1       1       5 gem.txt

当我用python3在这两个文件中阅读时,我得到了看似不同的信息

代码语言:javascript
复制
$ python3
Python 3.7.3 (default, Dec 13 2019, 19:58:14)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> with open('gem.txt', 'r') as f:
...   gem = f.read()
...
>>> gem
'\n'
>>> len(gem)
2
>>> ord(gem[0])
128142
>>>
>>>
>>> with open('utf', 'r') as f:
...   utf = f.read()
...
>>> utf
'"ð\x9f\x92\x8e"\n'
>>> len(utf)
7
>>> for char in utf:
...   print(ord(char))
...
34
240
159
146
142
34
10
>>>

基于这种行为,我有几个问题:

  1. Facebook返回的数据是否编码错误?此页显示了宝石表情符号正确的Unicode指针为U+1F48E,相应的UTF-8 0xF0 0x9F 0x92 0x8E表示与od输出的字节匹配。
  2. 有什么方法可以解析Facebook返回的字符串吗?似乎前面的问题建议在转换文本之前使用正则表达式,是否需要这样做?
  3. gem.txt的长度为5字节,减去换行符4字节来表示表情符号。这对我来说很有意义,因为它的UTF-8表示需要4个字节。为什么utf文档会列出11个字节(大概是10个没有换行符)?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-29 06:04:06

看起来,您的JSON文件的内容确实被弄得焦头烂额。用错误的编码曲解。

代码语言:javascript
复制
>>> import json
>>> # That's how it should look:
>>> print(json.dumps(''))
"\ud83d\udc8e"
>>> # That's what you got:
>>> mojibaked = ''.encode('utf8').decode('latin1')
>>> print(json.dumps(mojibaked))
"\u00f0\u009f\u0092\u008e"

检查是否可以修复如何创建JSON文件。拉丁文-1是某些工具/协议中的缺省值。最方便的是,您始终可以将任何字节流解码为拉丁文-1,没有例外。不过,它可能会破坏您的输入,就像这里所发生的一样。

如果无法修复源,则可以通过反向执行编码往返来恢复:

代码语言:javascript
复制
>>> mojibaked = json.loads('"\\u00f0\\u009f\\u0092\\u008e"')
>>> mojibaked
'ð\x9f\x92\x8e'
>>> mojibaked.encode('latin1').decode('utf8')
''
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62628204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档