Python/Json:期望用双引号括起来的属性名

我一直在试图找出一个在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格式的数据。

任何建议都将不胜感激。

607504 次浏览

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

您需要修复数据的来源。

JSON字符串必须使用双引号。JSON python库强制这样做,所以你无法加载你的字符串。你的数据应该是这样的:

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

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

这样的:

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

不是JSON。
: < / p >

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

是JSON。

< p > 编辑:
一些评论者认为,上述内容还不够。
JSON规范- RFC7159声明字符串以引号开始和结束。这是"
单引号'在JSON中没有语义,只允许在字符串中

我检查了你的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"
}]
}
}

正如它清楚地说错了,名字应该用双引号括起来,而不是单引号。您传递的字符串不是有效的JSON。它应该是这样的

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

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

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

 Expecting property name enclosed in double quotes

添加json。转储开始创建正确格式的JSON &解决问题。

因为JSON只允许用双引号括住字符串,你可以这样操作字符串:

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

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

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

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

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

$ pip install jsbeautifier
$ js-beautify file.js

在我的例子中,双引号不是问题。

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

{'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)

这对我很有效。

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

x = "{'inner-temperature': 31.73, 'outer-temperature': 28.38, 'keys-value': 0}"


x = x.replace("'", '"')
j = json.loads(x)
print(j['keys-value'])

输出

>>> 0
使用json.dumps()方法总是理想的。 为了消除这个错误,我使用了以下代码

json.dumps(YOUR_DICT_STRING).replace("'", '"')
with open('input.json','r') as f:
s = f.read()
s = s.replace('\'','\"')
data = json.loads(s)

这对我来说非常有效。谢谢。

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}}}}

注意到“真正的”值?使用这个函数可以对布尔值进行双重检查。这将涵盖这些情况

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

另外,确保你没有做出

x = json.loads(x)

它必须是另一个变量。

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)

这样问题就解决了。

我在手动编辑JSON时多次遇到过这个问题。 如果有人在没有注意到的情况下从文件中删除了一些内容,则会抛出相同的错误

例如,如果您的JSON最后"}"则会抛出相同的错误。

所以如果你手动编辑你的文件,确保你的格式像JSON解码器所期望的那样,否则你会遇到同样的问题。

使用eval函数。

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

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

在我的例子中,即使在我的字符串中用"替换了',我仍然得到ValueError。我最终意识到,一些类似引号的unicode符号已经进入了我的字符串:

 “  ”  ‛  ’  ‘  `  ´  ″  ′

要清除所有这些,你可以通过一个正则表达式传递你的字符串:

import re


raw_string = '{“key”:“value”}'


parsed_string = re.sub(r"[“|”|‛|’|‘|`|´|″|′|']", '"', my_string)


json_object = json.loads(parsed_string)


我有同样的问题,我所做的是用双引号替换单引号,但更糟糕的是,当我有一个逗号的json对象的最后一个属性时,我有同样的错误。因此,在使用json.loads()函数之前,我使用python中的regex来替换它。(注意“load "”结尾的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)


使用的正则表达式返回每个逗号后面跟着换行符和"}",用"代替它。

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

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")

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

如果你有一个转换字典到字符串和双引号的问题,这可以帮助:

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

json。加载文档< / >

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"
}]}

解决方案1 (非常危险)

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

parsed_json = eval(your_json)

解决方案2 (无风险)

你可以使用python默认包含的ast库,它也可以安全地计算表达式。

import ast


parsed_json = ast.literal_eval(your_json)

下面的代码片段将有助于将数据转换为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)

我有这个错误试图规范化嵌套的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语法的部分。在这种情况下,我建议4步解决方案:

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

  2. 所有(剩余)双引号替换为一些在您的文档中不存在的特殊字符,例如``。你可以用re.sub("\"", "``", x)来做。

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

你现在可以加载JSON文档,并将其读入Pandas DataFrame中pd.json_normalize(df["json_col"].apply(json.loads))

  1. 如果你愿意,你可以用"替换回所有的``(或你选择的一个特殊字符)。

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

如果你想将带有单引号的json字符串转换为python dict,请使用ast.literaleval()

>>> import ast
>>> payload = "{'hello': 'world'}"
>>> ast.literal_eval(payload)
{'hello': 'world'}
>>> type(ast.literal_eval(payload))
<class 'dict'>

这将把有效负载转换为python字典。

我的问题是,我复制并粘贴了一个JSON片段,所使用的双引号在某种程度上是一个不同的、无法识别的双引号字符。我的文件在替换双引号后是有效的JSON。

这很简单

import json


my_str = '{"message_type": "fixed_price_difference", "message": "Hello hello"}'


print(type(json.loads(my_str)), json.dumps(my_str))


Output:
<class 'dict'> "{\"message_type\": \"fixed_price_difference\", \"message\": \"Hello hello\"}"

比如语法就很重要

语法错误,不正确: my_str = "{'message_type': 'fixed_price_difference', 'message': 'Hello hello"}' < / p > < p >正确的语法: my_str = '{"message_type": "fixed_price_difference", "message": "Hello hello"}' < / p > < p >最后: 表示字符串以引号开始和结束。

因为你的字符串是一个有效的JavaScript对象,你可以使用Js2Py库:

import js2py


content = """x = {'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}"""
content = js2py.eval_js(content)


print(content.to_dict())

在我的例子中,错误不在json.loads(data)

我已经做了一些错误与json结构之前,所以有一个不足的部分在它,如

{'http://example.org/about': {'http://purl.org/dc/terms/title':

这也是引起这个错误的情况