在python脚本中,我正在解析
的返回
gsettings get org.gnome.system.proxy ignore-hosts
看起来它应该格式正确JSON
['localhost', '127.0.0.0/8']
但是,当将此输出传递给json.loads时,它会抛出
ValueError: No JSON object could be decoded
我通过以下方式调用gsettings:
import subprocess
proc = subprocess.Popen(["gsettings", "get", "org.gnome.system.proxy", "ignore-hosts"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout,stderr = proc.communicate()
将"['localhost', '127.0.0.0/8']\n"
分配给stdout
。
然后我剥离换行符并传递给json.loads:
ignore = json.loads(stdout.strip("\n"))
但是,这会引发ValueError
。
我已将问题跟踪到由单引号或双引号定义的字符串,如下面的代码段所示:
# tested in python 2.7.3
import json
ignore_hosts_works = '["localhost", "127.0.0.0/8"]'
ignore_hosts_fails = "['localhost', '127.0.0.0/8']"
json.loads(ignore_hosts_works) # produces list of unicode strings
json.loads(ignore_hosts_fails) # ValueError: No JSON object could be decoded
import string
table = string.maketrans("\"'", "'\"")
json.loads(string.translate(ignore_hosts_fails, table)) # produces list of unicode strings
为什么ignore_hosts_fails
在没有交换报价类型的情况下无法成功解析json.loads
?
如果它可能很重要,我用Python 2.7.3运行Ubuntu 12.04。
答案 0 :(得分:4)
string = quotation-mark *char quotation-mark
[...]
quotation-mark = %x22 ; "
JSON字符串 必须 使用"
引号。
您可以使用ast.literal_eval()
:
>>> import ast
>>> ast.literal_eval("['localhost', '127.0.0.0/8']")
['localhost', '127.0.0.0/8']
答案 1 :(得分:0)
因为RFC 7159这样说。 JSON文档中的字符串用双引号括起来。
答案 2 :(得分:0)
JSON 不是只是JavaScript。
根据规范pdf或json.org对JSON字符串进行双引号。
JSON对象键是字符串。
您必须为字符串和键使用双引号(遵循规范)。许多JSON解析器将更加宽容。
来自object
定义:
对象结构表示为一对围绕零个或多个名称/值对的大括号标记。
名称是一个字符串。每个名称后面都有一个冒号标记,将名称与值分开。单个逗号标记将值与以下名称分开。
来自string
定义:
字符串是一系列用引号(U + 0022)包装的Unicode代码点。
U+0022
是(双)引号:"
。
答案 3 :(得分:0)
如前所述,这是无效的JSON。要解析,还有两种可能性:使用demjson
或yaml
>>> demjson.decode(" ['localhost', '127.0.0.0/8']")
[u'localhost', u'127.0.0.0/8']
>>> yaml.load(" ['localhost', '127.0.0.0/8']")
['localhost', '127.0.0.0/8']
答案 4 :(得分:0)
是的,它关心有效的json。但是你可以调整Simple json代码来解析这个Unquoted和单引号的json字符串。
我在这篇文章中给出了答案