我有一个包含连接字符串的JSON文件:
abc.json
{
"host":"1.2.3.4",
"user":"abc",
"passwd":"s&]\yz$&u42/",
"dbname":"sample",
"port":2341
}
这是我的Python脚本,它试图读取数据:
import psycopg2 as pg
dbconn = "C:\abc.json"
with open(dbconn) as conn_file:
conn = json.load(conn_file)
它给了我这个错误:
json.decoder.JSONDecodeError: Invalid \escape: line 4 column 16 (char 53)
如何解决此错误?
答案 0 :(得分:3)
您的文件无效:JSON中没有\y
这样的转义序列,裸露的反斜杠本身必须进行转义:\\
。
如果可以,最简单的解决方案是通过转义反斜杠来修复您的文件,使其成为有效的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
为简单起见,上面的函数采用字符串而不是文件。
它也是一种破坏坚果的大锤。方法,反复尝试加载整个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/
在您的情况下,您要从文件中读取字符串,然后调用该函数:
dbconn = "C:\abc.json"
with open(dbconn) as conn_file:
conn_doc = conn_file.read()
conn = permissive_json_loads(conn_doc)
答案 1 :(得分:0)
Python> = 2.7.15似乎产生与Python3相同的错误消息:
test = """
{
"host":"1.2.3.4",
"user":"abc",
"passwd":"s&]\yz$&u42/",
"dbname":"sample",
"port":2341
}
"""
print json.loads(test)
错误:
ValueError:无效\ escape:第5行第16列(字符54)
稍微修改@Zero Piraeus's代码使其可以在Python2.7下工作:
import json
import re
def permissive_json_loads(text):
_rePattern = re.compile(r'''(\d+)\)$''', re.MULTILINE)
i = 0
# Make sure the loop is going to terminate.
# There wont be more iterations than the double amout of characters
while True:
i += 1
if i > len(text) * 2:
return
try:
data = json.loads(text)
except ValueError, exc:
exMsg = str(exc)
if exMsg.startswith('Invalid \\escape'):
m = re.search(_rePattern, exMsg)
if not m:
return
pos = int(m.groups()[0])
print "Replacing at: %d" % pos
text = text[:pos] + '\\' + text[pos:]
else:
raise
else:
return data
text = """
{
"host":"1.2.3.4",
"user":"abc",
"passwd":"s&]\yz$&u42/",
"dbname":"sample",
"port":2341
}
"""
i = permissive_json_loads(text)
print i
打印:
Replacing at position: 54
{u'passwd': u's&]\\yz$&u42/', u'host': u'1.2.3.4', u'port': 2341, u'user': u'abc', u'dbname': u'sample'}