有效的json期望转义的换行符被编码为' \\ n',带有两个反斜杠。我有包含我想要保存到文件的换行符的数据。这是一个简化版本:
data = {'mystring': 'Line 1\nLine 2'}
我可以使用json.dumps()编码:
import json
json_data = json.dumps(data)
json_data
# -> '{"mystring": "Line 1\\nLine 2"}'
当我打印它时,换行符显示为' \ n'而不是' \\ n' (我觉得奇怪,但我可以忍受):
print(json_data)
# -> {"mystring": "Line 1\nLine 2"}
然而(这是问题)当我将其输出到文件时,文件的内容不再包含有效的json:
f = open('mydata.json', 'w')
f.write(json_data)
f.close()
如果我打开文件并阅读它,它包含:
{"mystring": "Line 1\nLine 2"}
但我希望如此:
{"mystring": "Line 1\\nLine 2"}
奇怪(我认为),如果我使用python&的open()读取文件,json数据被认为是有效的:
f = open('mydata.json', 'r')
json_data = f.read()
f.close()
json_data
# -> '{"mystring": "Line 1\\nLine 2"}'
...它解码好了:
json.loads(json_data)
# -> {u'mystring': u'Line 1\nLine 2'}
我的问题是为什么文件中的数据无效json ?如果我需要另一个 - 非Python - 应用程序来读取它可能是不正确的。如果我复制并粘贴文件内容并在其上使用json.loads()则失败:
import json
json.loads('{"mystring": "Line 1\nLine 2"}')
# -> ValueError: Invalid control character at: line 1 column 21 (char 20)
有人可以解释这是预期的行为还是我做错了什么?
答案 0 :(得分:2)
你遇到了忽略\
字符也是Python中的转义序列字符这一事实的陷阱。尝试打印出最后一个示例,而不是调用json.loads
:
>>> print('{"mystring": "Line 1\nLine 2"}')
{"mystring": "Line 1
Line 2"}
以上都不是有效的JSON。如果\
字符编码正确,该怎么办?
>>> print('{"mystring": "Line 1\\nLine 2"}')
{"mystring": "Line 1\nLine 2"}
好多了,你可以:
>>> json.loads('{"mystring": "Line 1\\nLine 2"}')
{'mystring': 'Line 1\nLine 2'}
或者,如果您真的希望能够从其他缓冲区复制一些文本并将其粘贴到您的实时解释器中进行解码,您可以考虑使用r
aw修饰符作为您的字符串:
>>> print(r'{"mystring": "Line 1\nLine 2"}')
{"mystring": "Line 1\nLine 2"}
>>> json.loads(r'{"mystring": "Line 1\nLine 2"}')
{'mystring': 'Line 1\nLine 2'}
看到\
不再使用换行符自动转义。
另请参阅:How do I handle newlines in JSON?并注意这不是严格存在于Python中的问题。
答案 1 :(得分:0)
原因是:
print(json_data)
# -> {"mystring": "Line 1\nLine 2"}
\\
是否是一个有效的转义序列,在尝试打印时会以单个反斜杠\
结束。
json文件中的数据是有效的,因为解析器能够解析它:)
这种混淆源于这样一个事实:当你尝试打印带有转义序列的字符串时,会解释它们。序列\\n
被解释为\n