【问题标题】:Python/Json:Expecting property name enclosed in double quotesPython/Json:期望用双引号括起来的属性名称
【发布时间】:2017-01-22 07:37:30
【问题描述】:

我一直在尝试找出一种在 Python 中加载 JSON 对象的好方法。 我发送这个 json 数据:

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

到后端,它将作为字符串接收,然后我使用json.loads(data) 解析它。

但每次我都遇到同样的异常:

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

我用谷歌搜索了它,但除了这个解决方案 json.loads(json.dumps(data)) 之外似乎没有任何效果,这对我个人来说似乎效率不高,因为它接受任何类型的数据,即使是非 json 格式的数据。

任何建议将不胜感激。

【问题讨论】:

  • 我的错误不是双引号。我在最后一个键值对之后添加了一个逗号,就像我们在 python 中所做的那样。你不会在 JSON 中这样做。
  • 总是使用json.dumps(),而不是仅仅写出python并希望python符号能在你的JavaScript阅读器中工作。
  • 我遇到了这个问题,因为我获取了print(jsonpickle_deserialized_object_string) 的结果并尝试使用它。出于某种原因,print() 将引号从 " 更改为 '
  • @Luv33preet,谢谢,解决了。但我希望 logger-msg 缺少逗号或其他东西,但这个错误并没有说明任何事情,

标签: python json parsing


【解决方案1】:

这个:

{
    'http://example.org/about': {
        'http://purl.org/dc/terms/title': [
            {'type': 'literal', 'value': "Anna's Homepage"}
        ]
     }
}

不是 JSON。
这个:

{
     "http://example.org/about": {
         "http://purl.org/dc/terms/title": [
             {"type": "literal", "value": "Anna's Homepage"}
          ]
      }
}

是 JSON。

编辑:
一些评论者认为以上内容还不够。
JSON specification - RFC7159 声明字符串以引号开头和结尾。那是 "。
单引号 ' 在 JSON 中没有语义含义,只能在字符串中使用。

【讨论】:

  • Thanx :) 我没有注意这一点,我在发送数据时使用了正确的 json 格式,但是在后端收到时,双引号被单引号替换!因此我得到了那个例外。
  • 这不是解决方案。一个解决方案会告诉他如何将字符串修改为有效的 json。
  • @FistOfFury 很抱歉,您的陈述是基于错误的假设,即任意无效的 JSON 字符串可以通过编程方式可靠地转换为有效字符串。这个问题的很多答案都试图通过将 ' 替换为 " 等等来解决这个问题。我是否必须给你一些简单的输入字符串示例,这会破坏这些“解决方案”?显然 OP 明白我们正在处理的不是JSON 并且能够继续 - 接受了我的回答。提示 - 输入字符串看起来更像 Python dict.__repr__() 方法的输出。
  • @ElmoVanKielmo 不会改变您的答案是陈述,而不是问题的答案这一事实。您没有提供上下文或解释。来这里寻找有关该问题的信息的人会感到失望。你可能帮助过 OP,但其他人没有那么多。
  • 一个简单明了的陈述通常会有很大帮助。特别是当周围有很多其他答案时。
【解决方案2】:

由于 JSON 只允许用双引号括起字符串,因此您可以像这样操作字符串:

str = str.replace("\'", "\"")

如果您的 JSON 包含转义的单引号 (\'),那么您应该使用更精确的以下代码:

import re
p = re.compile('(?<!\\\\)\'')
str = p.sub('\"', str)

这会将 JSON 字符串 str 中所有出现的单引号替换为双引号,在后一种情况下不会替换转义的单引号。

您也可以使用不那么严格的js-beautify:

$ pip install jsbeautifier
$ js-beautify file.js

【讨论】:

  • 不是一个好主意,因为它可以将所有的 's 替换为 "s 这是错误的:示例:'it's bad' -> "it"s bad" -> malformed string
  • @Reihan_amn 对于使用转义单引号的情况,我添加了一个更精确的正则表达式替代方案。
  • 我根据stackoverflow.com/a/63862387/1497139 中的讨论向github.com/WolfgangFahl/pyLoDStorage/blob/master/tests/… 添加了一个测试用例 testSingleQuoteToDoubleQuoteStackoverflow,它显示了结果的差异:{'cities': [{'name': "Upper Hell's Gate"}, {'name': "N'zeto"}] {"cities": [{"name": "Upper Hell's Gate"}, {"name": "N'zeto"}] {"cities": [{" name": "Upper Hell"s Gate"}, {"name": "N"zeto"}]
  • {'name': "Lubov' Mal'ceva", 'url': 'vk.com/id283041382', 'id': 'id283041382'} {'url': 'vk.com/id459518460', 'id': 'id459518460', 'name': "Pid'z Achill"} {'url': 'vk.com/id107236823', 'id ': 'id107236823', 'name': "Ksenia Anatol'evna"} {'url': 'vk.com/id513742225', 'id': 'id513742225', 'name': "Saida'lo卡莫洛夫"}
【解决方案3】:

就我而言,双引号不是问题。

最后一个逗号给了我同样的错误信息。

{'a':{'b':c,}}
           ^

为了去掉这个逗号,我写了一些简单的代码。

import json

with open('a.json','r') as f:
    s = f.read()
    s = s.replace('\t','')
    s = s.replace('\n','')
    s = s.replace(',}','}')
    s = s.replace(',]',']')
    data = json.loads(s)

这对我有用。

【讨论】:

  • +1 我可以确认这一点。尾随逗号确实会产生此错误消息。示例:echo '{"json":"obj",}' | python -m json.tool,当在 shell 中运行时,给出“期望用双引号括起来的属性名称:第 1 行第 15 列(字符 14)”。尾随逗号不是合法的 JSON,但如果 Python JSON 模块在这种情况下发出相关的错误消息会很好。
  • 太棒了!!!它确实有效! :D
【解决方案4】:
import ast

inpt = {'http://example.org/about': {'http://purl.org/dc/terms/title':
                                     [{'type': 'literal', 'value': "Anna's Homepage"}]}}

json_data = ast.literal_eval(json.dumps(inpt))

print(json_data)

这将解决问题。

【讨论】:

  • 这应该更高,因为它实际上回答了问题。
【解决方案5】:

解决方案 1 (非常危险)

你可以简单地使用 python eval 函数。

parsed_json = eval(your_json)

解决方案 2 (无风险)

您可以使用默认包含在 python 中的 ast 库,它还可以安全地评估表达式。

import ast

parsed_json = ast.literal_eval(your_json)

【讨论】:

  • 甚至ast.literal_eval 到“安全地评估表达式节点或包含 Python 表达式的字符串。”
【解决方案6】:

很简单,该字符串不是有效的 JSON。正如错误所说,JSON 文档需要使用双引号。

你需要修复数据的来源。

【讨论】:

  • 如果您无法控制数据的来源,您会怎么做?...
  • “您需要修复数据源”在大型组织中工作时并不总是可行的。有时您的数据格式有些不正确,您需要使其正常工作。
【解决方案7】:

我已经检查了你的 JSON 数据

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

在http://jsonlint.com/ 中,结果是:

Error: Parse error on line 1:
{   'http://example.org/
--^
Expecting 'STRING', '}', got 'undefined'

修改为以下字符串解决JSON错误:

{
    "http://example.org/about": {
        "http://purl.org/dc/terms/title": [{
            "type": "literal",
            "value": "Anna's Homepage"
        }]
    }
}

【讨论】:

  • 谢谢你的链接!
【解决方案8】:

JSON 字符串必须使用双引号。 JSON python 库强制执行此操作,因此您无法加载字符串。您的数据需要如下所示:

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

如果这不是您可以做的,您可以使用ast.literal_eval() 而不是json.loads()

【讨论】:

  • 这不是 Python 库的限制,而是 JSON 格式本身的限制。
  • 你是对的。但是,一些 JSON 解析器不强制使用双引号。我会更新我的答案。
  • 如果这个非 JSON 在单引号字符串中没有任何双引号,您所要做的就是在调用 json.loads() 之前将所有单引号字符串替换为双引号
  • 如果 JSON 字符串具有布尔值,则使用 ast.literal_eval 将导致 ValueError: malformed string。
  • @JeffSpicoli 是的,json 布尔值是真/假,注意小写 t/f。
【解决方案9】:

正如错误中明确指出的那样,名称应该用双引号而不是单引号引起来。您传递的字符串不是有效的 JSON。它应该看起来像

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

【讨论】:

    【解决方案10】:
    x = x.replace("'", '"')
    j = json.loads(x)
    

    虽然这是正确的解决方案,但是如果有这样的JSON可能会导致相当头疼-

    {'status': 'success', 'data': {'equity': {'enabled': True, 'net': 66706.14510000008, 'available': {'adhoc_margin': 0, 'cash': 1277252.56, 'opening_balance': 1277252.56, 'live_balance': 66706.14510000008, 'collateral': 249823.93, 'intraday_payin': 15000}, 'utilised': {'debits': 1475370.3449, 'exposure': 607729.3129, 'm2m_realised': 0, 'm2m_unrealised': -9033, 'option_premium': 0, 'payout': 0, 'span': 858608.032, 'holding_sales': 0, 'turnover': 0, 'liquid_collateral': 0, 'stock_collateral': 249823.93}}, 'commodity': {'enabled': True, 'net': 0, 'available': {'adhoc_margin': 0, 'cash': 0, 'opening_balance': 0, 'live_balance': 0, 'collateral': 0, 'intraday_payin': 0}, 'utilised': {'debits': 0, 'exposure': 0, 'm2m_realised': 0, 'm2m_unrealised': 0, 'option_premium': 0, 'payout': 0, 'span': 0, 'holding_sales': 0, 'turnover': 0, 'liquid_collateral': 0, 'stock_collateral': 0}}}}
    

    注意到 "True" 值了吗?使用它可以对布尔值进行双重检查。这将涵盖这些情况 -

    x = x.replace("'", '"').replace("True", '"True"').replace("False", '"False"').replace("null", '"null"')
    j = json.loads(x)
    

    另外,请确保您不要制作

    x = json.loads(x)
    

    它必须是另一个变量。

    【讨论】:

      【解决方案11】:

      我使用了这种方法并设法获得了所需的输出。我的脚本

      x = "{'inner-temperature': 31.73, 'outer-temperature': 28.38, 'keys-value': 0}"
      
      x = x.replace("'", '"')
      j = json.loads(x)
      print(j['keys-value'])
      

      输出

      >>> 0
      

      【讨论】:

        【解决方案12】:
        with open('input.json','r') as f:
            s = f.read()
            s = s.replace('\'','\"')
            data = json.loads(s)
        

        这对我来说效果很好。谢谢。

        【讨论】:

          【解决方案13】:

          以下代码 sn-p 将有助于将数据转换为 JSON。所有单引号都应该转换成双引号来jsonify数据。

          data = {
          "http://example.org/about": {
              "http://purl.org/dc/terms/title": [{
                  "type": "literal",
                  "value": "Anna's Homepage"
              }]
          }}
          parsed_data = data.replace("'", '"')
          data_json = json.loads(parsed_data)
          

          【讨论】:

            【解决方案14】:

            我有类似的问题。相互通信的两个组件使用队列。

            第一个组件在将消息放入队列之前没有执行 json.dumps。 所以接收组件生成的 JSON 字符串是单引号。这导致错误

             Expecting property name enclosed in double quotes
            

            添加 json.dumps 开始创建格式正确的 JSON 并解决了问题。

            【讨论】:

              【解决方案15】:

              正如其他答案所解释的那样,错误是由于传递给 json 模块的无效引号字符而发生的。

              在我的情况下,即使在我的字符串中将 ' 替换为 " 后,我仍然会收到 ValueError。我终于意识到,一些类似引号的 unicode 符号已经进入了我的字符串:

               “  ”  ‛  ’  ‘  `  ´  ″  ′ 
              

              要清除所有这些,您只需通过正则表达式传递字符串:

              import re
              
              raw_string = '{“key”:“value”}'
              
              parsed_string = re.sub(r"[“|”|‛|’|‘|`|´|″|′|']", '"', my_string)
              
              json_object = json.loads(parsed_string)
              
              

              【讨论】:

                【解决方案16】:

                对于任何想要快速修复的人,这只是将所有单引号替换为双引号:

                import json 
                
                predictions = []
                
                def get_top_k_predictions(predictions_path):
                    '''load the predictions'''
                    
                    with open (predictions_path) as json_lines_file:
                        for line in json_lines_file:
                            predictions.append(json.loads(line.replace("'", "\"")))
                            
                    
                get_top_k_predictions("/sh/sh-experiments/outputs/john/baseline_1000/test_predictions.jsonl")
                

                【讨论】:

                  【解决方案17】:

                  您可以使用json5 包https://pypi.org/project/json5/ 代替json 包。这个包可以处理单引号。解码函数为json5.loads(data),类似于json包。

                  【讨论】:

                    【解决方案18】:

                    如果您在将 dict 转换为字符串并使用双引号时遇到问题,这会有所帮助:

                    json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
                    

                    json.loads documentation

                    【讨论】:

                      【解决方案19】:

                      json 语法要求每个“key”和“value”都用引号引起来。这使它成为一种强大的数据格式。在以下示例中,我使用颜色和颜色作为键:

                      {"colors":[
                        {
                           "color":"red",
                           "value":"#f00"
                        },
                        {
                           "color":"green",
                           "value":"#0f0"
                        },
                        {
                           "color":"blue",
                           "value":"#00f"
                        },
                        {
                           "color":"cyan",
                           "value":"#0ff"
                        },
                        {
                           "color":"magenta",
                           "value":"#f0f"
                        },
                        {
                           "color":"yellow",
                           "value":"#ff0"
                        },
                        {
                           "color":"black",
                           "value":"#000"
                        }]}
                      

                      【讨论】:

                        【解决方案20】:

                        使用eval 函数。

                        它处理单引号和双引号之间的差异。

                        【讨论】:

                        • 永远不要在用户输入上使用 eval,也不要在 HTTP 请求中使用数据。这是一个巨大的安全问题。
                        【解决方案21】:

                        我遇到了同样的问题,我所做的是将单引号替换为双引号,但更糟糕的是,当我为 json 对象的最后一个属性使用逗号时,我遇到了同样的错误。所以在使用json.loads()函数之前,我在python中使用了正则表达式来替换它。 (注意“loads”末尾的 s)

                        import re
                        
                        with open("file.json", 'r') as f:
                             s = f.read()
                             correct_format = re.sub(", *\n *}", "}", s)
                             data_json = json.loads(correct_format)
                        
                        

                        使用的正则表达式返回每个逗号后跟一个换行符和“}”,用“}”替换它。

                        【讨论】:

                          【解决方案22】:

                          我在尝试规范化 Pandas 中的嵌套 JSON 列时遇到此错误。正如@Reihan_amn 所指出的,将所有单引号替换为双引号可能会影响实际内容。因此,当收到此错误时,您应该只替换 ' 应该是 JSON 语法中的 " 所在的位置。您可以使用以下正则表达式:

                          import re
                          import json
                          
                          invalid_json = """{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}"""
                          
                          valid_json = re.sub( "(?<={)\'|\'(?=})|(?<=\[)\'|\'(?=\])|\'(?=:)|(?<=: )\'|\'(?=,)|(?<=, )\'", "\"", invalid_json)
                          
                          print(json.loads(valid_json))
                          
                          

                          如果唯一的问题是单引号 (') 在您的原始格式错误的 JSON 文档中应该是双引号 (") 就足够了。但是,如果您的文档中的某处有双引号也是 JSON 语法 not 的一部分,那么您仍然会收到错误消息。在这种情况下,我建议采用 4 步解决方案:

                          1. 将所有属于 JSON 语法的双引号替换为单引号(与上面类似的正则表达式,但 ' 和 " 已交换)。

                          2. 用文档中没有的特殊字符替换 all(剩余的)双引号,例如``。您可以使用re.sub("\"", "``", x) 来完成。

                          3. 使用上面给出的正则表达式将 JSON 中双引号应该在的所有单引号替换为双引号。

                          您现在可以加载 JSON 文档并将其读入带有 pd.json_normalize(df["json_col"].apply(json.loads)) 的 Pandas DataFrame。

                          1. 如果需要,您可以将所有 ``(或您选择的特殊字符)替换为 "。

                          【讨论】:

                            【解决方案23】:

                            我强烈推荐使用像 JSON Prettifier 这样的 json 美化工具,因为它帮助我修复了我在 JSON 文件中出现的尾随逗号的错误,该错误产生了相同的错误。

                            【讨论】:

                              【解决方案24】:

                              最好使用json.dumps() 方法。 为了摆脱这个错误,我使用了以下代码

                              json.dumps(YOUR_DICT_STRING).replace("'", '"')
                              

                              【讨论】:

                                【解决方案25】:

                                当手动编辑 JSON 时,我多次遇到此问题。 如果有人在没有注意到的情况下从文件中删除某些内容,可能会引发同样的错误。

                                例如,如果您的 JSON 最后一个“}”丢失,则会引发相同的错误。

                                因此,如果您手动编辑文件,请确保按照 JSON 解码器的预期格式化,否则您会遇到同样的问题。

                                希望这会有所帮助!

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2019-01-04
                                  • 2019-04-24
                                  • 2021-10-15
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多