Valid json expects escaped newline characters to be encoded as '\\n', with two backslashes. I have data that contains newline characters that I want to save to a file. Here's a simplified version:
data = {'mystring': 'Line 1\nLine 2'}
I can encode it with json.dumps():
import json
json_data = json.dumps(data)
json_data
# -> '{"mystring": "Line 1\\nLine 2"}'
When I print it, the newline displays as '\n', not '\\n' (which I find odd but I can live with):
print(json_data)
# -> {"mystring": "Line 1\nLine 2"}
However (here's the problem) when I output it to a file, the content of the file no longer contains valid json:
f = open('mydata.json', 'w')
f.write(json_data)
f.close()
If I open the file and read it, it contains this:
{"mystring": "Line 1\nLine 2"}
but I was hoping for this:
{"mystring": "Line 1\\nLine 2"}
Oddly (I think), if I read the file using python's open(), the json data is considered valid:
f = open('mydata.json', 'r')
json_data = f.read()
f.close()
json_data
# -> '{"mystring": "Line 1\\nLine 2"}'
... and it decodes OK:
json.loads(json_data)
# -> {u'mystring': u'Line 1\nLine 2'}
My question is why is the data in the file not valid json? If I need another - non Python - application to read it it would probably be incorrect. If I copy and paste the file contents and use json.loads() on it it fails:
import json
json.loads('{"mystring": "Line 1\nLine 2"}')
# -> ValueError: Invalid control character at: line 1 column 21 (char 20)
Can anybody explain if this is the expected behaviour or am I doing something wrong?
JSON strings do not allow real newlines in its data; it can only have escaped newlines. Snowflake allows escaping the newline character by the use of an additional backslash character.
If you need to have a newline inside a string inside JSON you can use the two literal characters \n which means you will need to double the backslash to tell Python to produce a single regular backslash (instead of treating it as a special character).
In JSON object make sure that you are having a sentence where you need to print in different lines. Now in-order to print the statements in different lines we need to use '\\n' (backward slash). As we now know the technique to print in newlines, now just add '\\n' wherever you want.
Use the json.loads() function. The json. loads() function accepts as input a valid string and converts it to a Python dictionary. This process is called deserialization – the act of converting a string to an object.
You ran into the pitfall of neglecting the fact that the \
character is also an escape sequence character in Python. Try printing out the last example instead of calling json.loads
:
>>> print('{"mystring": "Line 1\nLine 2"}')
{"mystring": "Line 1
Line 2"}
No way the above is valid JSON. What if the \
character is correctly encoded?
>>> print('{"mystring": "Line 1\\nLine 2"}')
{"mystring": "Line 1\nLine 2"}
Much better, you can then:
>>> json.loads('{"mystring": "Line 1\\nLine 2"}')
{'mystring': 'Line 1\nLine 2'}
Alternatively, if you really appreciate being able to copy some text from some other buffer and paste it into your live interpreter to do decode, you may consider using the r
aw modifier for your string:
>>> 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'}
See that the \
is no longer automatically escaping with the newline.
Also see: How do I handle newlines in JSON? and note how this is not a problem that exists strictly within Python.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With