Python json.loads 报错 ValueError,期望分隔符

27

我正在将一个postgres表作为json提取。输出文件包含如下行:

{"data": {"test": 1, "hello": "I have \" !"}, "id": 4}

现在我需要使用json.loads在我的Python代码中加载它们,但是我遇到了这个错误:

Traceback (most recent call last):
  File "test.py", line 33, in <module>
    print json.loads('''{"id": 4, "data": {"test": 1, "hello": "I have \" !"}}''')
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting , delimiter: line 1 column 50 (char 49)
我发现解决方法是在\"中再添加一个\。所以,如果我传递以下内容:
{"data": {"test": 1, "hello": "I have \\" !"}, "id": 4}

使用json.loads,我得到了这个:

{u'data': {u'test': 1, u'hello': u'I have " !'}, u'id': 4}

有没有不添加额外\的方法?比如通过将参数传递给json.loads之类的方式?


1
大家好,我也遇到了同样的问题,有有效的解决方案吗? - Afraz Ahmad
5个回答

29

您可以指定所谓的“原始字符串”:

>>> print r'{"data": {"test": 1, "hello": "I have \" !"}, "id": 4}'
{"data": {"test": 1, "hello": "I have \" !"}, "id": 4}

他们不会解释反斜杠。

通常的字符串将\"转换为",因此您可以在由双引号限定的字符串中拥有"字符:

>>> "foo\"bar"
'foo"bar'

因此,从\""的转换并不是由json.loads完成,而是由Python本身完成的。


我正在逐行读取数据文件,因此我将字典存储在变量中。我尝试使用.replace("\\", r"\\").encode('string-escape'),但都没有起作用。 - AliBZ
在JSON中,"\""和Python一样表示'"'。如果输入文件中有\",它实际上是一个"。如果您出于某种原因仍想要r'\"',则需要使用.replace('"', '\\"') - Gandaro

9

试试这个:

json.loads(r'{"data": {"test": 1, "hello": "I have \" !"}, "id": 4}')

如果你已经将该字符串存储到一个变量当中,那么可以直接进行以下操作:
json.loads(data.replace("\\", r"\\"))

希望能帮到您!

1
很抱歉,它不起作用,'{"data": {"test": 1, "hello": "I have \" !"}, "id": 4}''{"data": {"test": 1, "hello": "I have \" !"}, "id": 4}'.replace("\\", r"\\") 是完全相同的。 - AliBZ
@AliBZ 这不起作用是因为你在字符串前面缺少了 r。复制并粘贴我的第一个示例,那样就可以工作了。 - cdonts
我将字符串存储在一个变量中,这就是为什么我使用了你的第二个示例。 - AliBZ
@AliBZ 好的,唯一的方法是使用 replace 手动将 " 替换为 \\" - cdonts

2

尝试使用三引号 r""", 不需要考虑 \ 的问题。

json_string = r"""
{
    "jsonObj": []
}
"""
data = json.loads(json_string)

1

尝试使用source.replace('""', '')或者替换它,因为源代码中的""会使得json.loads(source)无法区分它们。


1
对于我的实例,我写了以下内容:
STRING.replace("': '", '": "').replace("', '", '", "').replace("{'", '{"').replace("'}", '"}').replace("': \"", '": "').replace("', \"", '", "').replace("\", '", '", "').replace("'", '\\"')

并且像魔法一样运作良好。

我不知道为什么你会有负面评价。我尝试了你的代码,它可以运行。 - Mohamed Imran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接