JQ 无法解析 Unicode 表情符号字符。它是有效的 JSON 吗?

Joe*_*Joe 4 unicode standards json clojure jq

我有一个 JSON 文件,其中包含来自 Clojuredata.json库的JSON 。数据来自 Twitter,人们似乎笑得很开心。

$ cat /tmp/myfile | jq .
Run Code Online (Sandbox Code Playgroud)

我得到:

parse error: Invalid \uXXXX\uXXXX surrogate pair escape at line 1, column 14862268
Run Code Online (Sandbox Code Playgroud)

违规部分是:

$ cut -c 14862258-14862269 /tmp/2017-02-23-2
79-7\ud83d",
Run Code Online (Sandbox Code Playgroud)

所以,这个转义码是在真实的 JSON 文件中找到的,JQ 无法读取。

echo '"\ud83d"' | jq .
Run Code Online (Sandbox Code Playgroud)

Fileformat.info 似乎建议它应该成对出现:

SMILING FACE WITH OPEN MOUTH
"\uD83D\uDE03"
Run Code Online (Sandbox Code Playgroud)
  1. 这真的是在 JSON 文件中找到的无效字符吗?我的 JSON 在技术上无效吗?

  2. 是否有一个简单的实用程序可以通过管道传输数据以在 JQ 之前去除这些字符?或者我可以让JQ放松它的解释吗?

pea*_*eak 7

JSON规范说:

字符串是零个或多个 Unicode 字符 [UNICODE] 的序列。

从这个意义上说,字符串 "\ud83d" 不是有效的 JSON(“+UD83D 不是有效的 Unicode 字符”),即使它符合 JSON ABNF。正如标准文档所说,字符串规范和 ABNF 之间存在差异:

本规范中的 ABNF 允许成员名称和字符串值包含不能编码 Unicode 字符的位序列;例如,“\uDEAD”(单个未配对的 UTF-16 代理)。已经观察到这样的实例,例如,当库截断 UTF-16 字符串而不检查截断是否拆分代理对时。接收包含此类值的 JSON 文本的软件的行为是不可预测的......

所以可以公平地说:

  1. "\uD83D" 不是严格有效的 JSON,即使它符合 ABNF;

  2. jq 在这里是它的权利;

  3. jsonlint 接受“\uD83D”是错误的。

“……去掉这些字符”

参见例如如何从文本文件中删除非 UTF-8 字符