为什么json.loads关心使用哪种类型的引号?

时间:2015-02-11 21:27:50

标签: python json string python-2.7

在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。

5 个答案:

答案 0 :(得分:4)

来自JSON RFC 7159

  string = quotation-mark *char quotation-mark
     

[...]

  quotation-mark = %x22      ; "

JSON字符串 必须 使用"引号。

您可以使用ast.literal_eval()

将该列表解析为Python文字
>>> 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。

根据规范pdfjson.org对JSON字符串进行双引号。

JSON对象键是字符串。

必须为字符串和键使用双引号(遵循规范)。许多JSON解析器将更加宽容。

来自object定义:

  

对象结构表示为一对围绕零个或多个名称/值对的大括号标记。

     

名称是一个字符串。每个名称后面都有一个冒号标记,将名称与值分开。单个逗号标记将值与以下名称分开。

来自string定义:

  

字符串是一系列用引号(U + 0022)包装的Unicode代码点。

U+0022是(双)引号:"

答案 3 :(得分:0)

如前所述,这是无效的JSON。要解析,还有两种可能性:使用demjsonyaml

>>> 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字符串。

我在这篇文章中给出了答案

Single versus double quotes in json loads in Python