Python/Json:期望用双引号括起来的属性名称
Posted
技术标签:
【中文标题】Python/Json:期望用双引号括起来的属性名称【英文标题】:Python/Json:Expecting property name enclosed in double quotes 【发布时间】: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 缺少逗号或其他东西,但这个错误并没有说明任何事情,
见***.com/a/63862387/1497139 快速修复
【参考方案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 对于使用转义单引号的情况,我添加了一个更精确的正则表达式替代方案。 谢谢我现在改用***.com/a/63862387/1497139 我根据***.com/a/63862387/1497139 中的讨论向github.com/WolfgangFahl/pyLoDStorage/blob/master/tests/… 添加了一个测试用例 testSingleQuoteToDoubleQuote***,它显示了结果的差异:'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"]就我而言,双引号不是问题。
最后一个逗号给了我同样的错误信息。
'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 步解决方案:
将所有属于 JSON 语法的双引号替换为单引号(与上面类似的正则表达式,但 '
和 "
已交换)。
用文档中没有的特殊字符替换 all(剩余的)双引号,例如``
。您可以使用re.sub("\"", "``", x)
来完成。
使用上面给出的正则表达式将 JSON 中双引号应该在的所有单引号替换为双引号。
您现在可以加载 JSON 文档并将其读入带有 pd.json_normalize(df["json_col"].apply(json.loads))
的 Pandas DataFrame。
-
如果需要,您可以将所有
``
(或您选择的特殊字符)替换为 "
。
【讨论】:
【参考方案23】:我强烈推荐使用像 JSON Prettifier 这样的 json 美化工具,因为它帮助我修复了我在 JSON 文件中出现的尾随逗号的错误,该错误产生了相同的错误。
【讨论】:
【参考方案24】:最好使用json.dumps()
方法。
为了摆脱这个错误,我使用了以下代码
json.dumps(YOUR_DICT_STRING).replace("'", '"')
【讨论】:
【参考方案25】:当手动编辑 JSON 时,我多次遇到此问题。 如果有人在没有注意到的情况下从文件中删除某些内容,可能会引发同样的错误。
例如,如果您的 JSON 最后一个“”丢失,则会引发相同的错误。
因此,如果您手动编辑文件,请确保按照 JSON 解码器的预期格式化,否则您会遇到同样的问题。
希望这会有所帮助!
【讨论】:
以上是关于Python/Json:期望用双引号括起来的属性名称的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jenkins 管道上的 AWS cli “期望用双引号括起来的属性名称”