【问题标题】:JSON decode with un-escaped double quotes使用未转义的双引号进行 JSON 解码
【发布时间】:2019-10-06 19:11:30
【问题描述】:

请参阅以下来自源的响应 JSON。来源不灵活,无法在其末尾进行更改。挑战在于解码“结果”中的键值对。

{"result":"{\"key1\" : \"value with \"n,a.\".\" , \"key2\":\"value with \"n.a.\".\" }"}

结果中的嵌套 JSON:

{"key1" : "value with "n,a."." , "key2":"value with "n.a."."}

我正在使用python进行解码。

json_string = '{\"result\":\"{\\"key1\\" : \\"value with \\"n,a.\\".\\" , \\"key2\\":\\"value with \\"n.a.\\".\\"}\"}'

#The following string with no double quotes within value part works as expected
#json_string = '{\"result\":\"{\\"key1\\" : \\"value with n,a.\\" , \\"key2\\":\\"value with n.a. .\\"}\"}'

data1 = json.loads(json_string)

data1['result']
# '{"key1" : "value with "n,a."." , "key2":"value with "n.a."."}'

data_dict_string = data1['result']
json_stringp = "[{0}]".format(data_dict_string)
data_list = json.loads(json_stringp)

如预期的那样存在双引号会导致以下错误,

JSONDecodeError: Expecting ',' delimiter: line 1 column 25 (char 24)

如何去除 JSON 值部分的双引号?

【问题讨论】:

  • 来自“源”的 JSON 已损坏,可能无法自动修复。
  • 来源已经接受了这个缺陷,但表示他们最终无法处理它
  • 好吧,他们违反了标准,他们修复了它。就是这么简单。您首先在计算机科学中学到的一件事是,该陈述不必是真的。
  • 您也可以编写一些启发式方法来最终修复它,但在某些特殊情况下肯定会失败。例如。您可以将 ", " .... ": " 作为值内的文本,这是完全合法的,并且没有进一步了解内容,您无法判断这是否只是值的一部分或定义了新的键、值对。标准的存在是有原因的。
  • 我投票决定将此问题作为离题结束,因为它寻求解决组织(如果不是法律)问题的技术解决方案。

标签: python json


【解决方案1】:

编辑:可能有一个实际的解决方案,详情如下。

他们的 JSON 肯定完全损坏了,在正常情况下,这不应该由您来修复。

没有安全的方法来扭转这种损坏,因为如您所见,当转义字符被剥离时,信息会丢失,因此结果是模棱两可的:

"{\"abc\": \"def\": \"ghi\"}" 可以表示"{\"abc\": \"def\\": \\"ghi\"}"(值为def": "ghi)或"{\"abc\\": \\"def\": \"ghi\"}"(键为abc": "def)

如果数据结构相当简单并且不包含任何其他问题,您可以应用一些启发式方法。

例如,如果结构是扁平的并且键都是字母数字,您可以尝试识别潜在的键 (/(\{|\\", )\\"([a-z]+)\\": \\"/),然后尝试将它们之间/之后的内容解析为值。

如果可能存在嵌套对象(更不用说任何字符串包含进一步编码错误的 JSON),它会变得更加复杂。

基本上,这超出了“缺陷”的范围 - 您正在尝试在这里解读鸡蛋。


附录:计算机科学方面,我想技术上可以描述这个问题,甚至有可能解决它(即,列举可能被解码的候选结构来自给定的字符串,希望很少,然后您可以进一步验证以找到正确的字符串)。 JSON 由context-free grammar 描述,删除转义字符会将其变为ambiguous grammar(即,具有多个语法树产生相同字符串的语法)。有一些解析算法可以在(最坏的情况下)立方时间 O(n^3) 中处理这个问题。

据我所知,GNU Bison 实现了这个解析器,它以 Python 库的形式提供:http://freenet.mcnabhosting.com/python/pybison/

因此,如果您别无选择,并且可以将“损坏的 JSON”的语法形式化,那最终可能会成为最稳健(但也相当复杂)的方法。

【讨论】:

  • 我正在寻找类似的启发式方法。使用正则表达式应该仍然可以隔离第二个键的值。
【解决方案2】:

这是使用枚举器解决的。分享到被问到答案的解决方案的链接 Replace escaped double quotes to single quotes in Python using regex

解决方案代码:

import json
js = r'{"result":"{\"key\":\"How are you? \"Great!\" he said. \"Coffee ?\"\"},{\"key\":\" 2. \"Why not, sure.\". They walked away\"}"}'

data1 = json.loads(js)
s = data1['result']

good_characters = [":","{","}",","]
result = "" 

for key, value in enumerate(s):

    if ((value == "\"" and s[key-1] not in good_characters) and (value == "\"" and s[key+1] not in good_characters) or (value == "\"" and s[key-1] == "," and s[key-2] != "\"")):
        result += '\''   
    else:
        result += value        
#print(result)
json_string = "[{0}]".format(result)
data_list = json.loads(json_string)
print(data_list)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 2021-02-28
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多