Alex Rivera | Logout

Python json.loads fails with `ValueError: Invalid control character at: line 1 column 33 (char 33)`

Asked 2012-02-15T14:44:29.347
61

I have a string like this:

s = u"""{"desc": "\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br \/>\r\nhttp:\/\/www.zhenpin.com\/ <br \/>\r\n<br \/>\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026"}"""

json.loads(s) returns error message like this:

ValueError: Invalid control character at: line 1 column 33 (char 33)

Why does this error occur? How can I solve this problem?

Edit
Report

1 Answer

12

The problem is that the character at index 33 is a carriage return control character.

>>> s[33]
u'\r'

According to the JSON spec, valid characters are:

  • Any Unicode character except: ", \, and control-characters (ord(char) < 32).

  • The following character sequences are allowed: \", \\, \/, \b (backspace), \f (form feed), \n (line-feed/new-line), \r (carriage return), \t (tab), or \u followed by four hexadecimal digits.

However, in Python you're going to have to double escape control characters (unless the string is raw) because Python also interprets those control characters.

>>> s = ur"""{"desc": "\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br \/>\r\nhttp:\/\/www.zhenpin.com\/ <br \/>\r\n<br \/>\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026"}"""
>>> json.loads(s)
{u'desc': u'\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br />\r\nhttp://www.zhenpin.com/ <br />\r\n<br />\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026'}

References:

answered 2012-02-15T14:55:11.553

Your Answer