我有一个JSON文件,其中包含来自Clojure< data.json
库的JSON。数据来自Twitter,人们似乎对此微笑。
$ cat /tmp/myfile | jq .
我明白了:
parse error: Invalid \uXXXX\uXXXX surrogate pair escape at line 1, column 14862268
违规部分是:
$ cut -c 14862258-14862269 /tmp/2017-02-23-2
79-7\ud83d",
所以,这个转义代码是在真正的JSON文件中找到的,JQ无法读取它。
echo '"\ud83d"' | jq .
Fileformat.info seems to suggest它应该成对出现:
SMILING FACE WITH OPEN MOUTH
"\uD83D\uDE03"
这是否真的是在JSON文件中找到的无效字符?我的JSON在技术上是无效的吗?
是否有一个简单的实用程序,我可以通过管道数据在JQ之前删除这些字符?或者我可以让JQ放松它解释吗?
答案 0 :(得分:4)
字符串是零个或多个Unicode字符的序列[UNICODE]。
从这个意义上讲,字符串“\ ud83d”无效JSON("+UD83D is not a valid Unicode character"),即使它符合JSON ABNF。正如标准文件所说,字符串规范与ABNF之间存在差异:
本规范中的ABNF允许成员名称和 字符串值包含不能编码Unicode的位序列 字符;例如,“\ uDEAD”(单个未配对的UTF-16 代孕)。例如,在何时观察到这种情况 库会截断UTF-16字符串而不检查是否存在 截断分割代理对。软件的行为 收到包含这些值的JSON文本是不可预测的......
所以说:
“\ uD83D”不是严格有效的JSON,即使它符合ABNF;
jq在此权限范围内;
jsonlint接受“\ uD83D”是错误的。
答案 1 :(得分:2)
它绝对是有效的json,但代码单元D83D
本身无效。请记住,jq不只是解释json,而是试图获得它的价值。所以这不仅仅是json消耗的json中存储的字符流,它是一个具有明确值的字符串。
这个值是一个高代理,它必须成对出现,你的输入显然没有。因此,文件中编码的字符串虽然是有效的json,但并不代表jq尝试解析的有效unicode字符串。
如果你想使用jq解析它,你需要浏览你的json并完成这对。
如果你至少可以确保它是有效的json,你可以使用正则表达式来扫描数据以搜索不匹配的代理。像这样:
\\u[Dd][89ABab][0-9A-Fa-f]{2}(?!\\u[Dd][C-Fc-f][0-9A-Fa-f]{2})
|
(?<!\\u[Dd][89ABab][0-9A-Fa-f]{2})\\u[Dd][C-Fc-f][0-9A-Fa-f]{2}
然后你可以将它们脱掉或者对失踪的代理进行最好的猜测。