如何从带有未转义反斜杠的 JSON 文件中读取?

use*_*101 9 python json escaping python-2.7

我有一个包含连接字符串的 JSON 文件:

abc.json

{
  "host":"1.2.3.4",
  "user":"abc",
  "passwd":"s&]\yz$&u42/",
  "dbname":"sample",
  "port":2341
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试读取数据的 Python 脚本:

 import psycopg2 as pg
 dbconn = "C:\abc.json"
 with open(dbconn) as conn_file:
     conn = json.load(conn_file)
Run Code Online (Sandbox Code Playgroud)

它给了我这个错误:

json.decoder.JSONDecodeError: Invalid \escape: line 4 column 16 (char 53)
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个错误?

Zer*_*eus 7

您的文件无效:没有像\yJSON这样的转义序列,因此必须对裸反斜杠本身进行转义:\\.

如果可以,最简单的解决方案是通过转义反斜杠来修复您的文件,使其成为有效的 JSON。

如果由于某种原因你不能,可以编写一个包装器来json.loads()捕获这个特定的错误并修补源文本:

import json
from json.decoder import JSONDecodeError

def permissive_json_loads(text):
    while True:
        try:
            data = json.loads(text)
        except JSONDecodeError as exc:
            if exc.msg == 'Invalid \\escape':
                text = text[:exc.pos] + '\\' + text[exc.pos:]
            else:
                raise
        else:
            return data
Run Code Online (Sandbox Code Playgroud)

为了简单起见,上面的函数接受一个字符串而不是一个文件。

这也是一种“大锤破解坚果”的方法,反复尝试加载整个 JSON 文档并在发现它们时修复任何未转义的反斜杠——这对于很少有问题的小型 JSON 文档来说是合理的,但如果你不适合正在处理包含许多这些未转义的反斜杠错误的大型 JSON 文档。

这是在行动:

>>> print(text)
{
  "host":"1.2.3.4",
  "user":"abc",
  "passwd":"s&]\yz$&u42/",
  "dbname":"sample",
  "port":2341
}

>>> config = permissive_json_loads(text)
>>> print(config['passwd'])
s&]\yz$&u42/
Run Code Online (Sandbox Code Playgroud)

在你的情况下,你会从你的文件中读入一个字符串,然后调用函数:

 dbconn = "C:\abc.json"
 with open(dbconn) as conn_file:
     conn_doc = conn_file.read()
 conn = permissive_json_loads(conn_doc)
Run Code Online (Sandbox Code Playgroud)