0

I'm doing something very similar to what this user was doing: trying to load a javascript object declaration into a python dictionary. However, unlike that user, the property names aren't enclosed in quotes.

>>> simplejson.loads('{num1: 1383241561141, num2: 1000}')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/lalalal/site-packages/simplejson/__init__.py", line 385, in loads
    return _default_decoder.decode(s)
  File "/Users/lalalal/site-packages/simplejson/decoder.py", line 402, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/Users/lalalal/site-packages/simplejson/decoder.py", line 418, in raw_decode
    obj, end = self.scan_once(s, idx)
simplejson.decoder.JSONDecodeError: Expecting property name: line 1 column 1 (char 1)

It'd be just splendid if I had the correct JSON notation:

>>> simplejson.loads('{"num1": 1383241561141, "num2": 1000}')
{'num1': 1383241561141, 'num2': 1000}

But, I don't. How can I work around this? Maybe it comes down to something as simple as a regex?

Edit: This regex that Martijn wrote has me halfway there, it just doesn't work if I have trailing whitespace after the braces which happens in some of my example data, e.g. { num1: 1383241561141, num2: 1000}'

4
  • i would use a regexp to quote the keys, then parse it as JSON. (/, (\w)+:/g, ', "$1":') and then manually cleanup the string for the first and last key using string methods. that way JSON still does the heavy lifting and you just need to scrub a few predictable strings in a predictable way. Commented Nov 2, 2013 at 18:55
  • @dandavis What's that snippet supposed to be? A call to re.sub? Commented Nov 2, 2013 at 18:59
  • 1
    its the args to a call to JS's replace method. python should have something related, it's just admittedly been a long time since i used python, forgive me. Commented Nov 2, 2013 at 19:06
  • No worries. It threw me off because their regex grammar is slightly different, but I understand the approach. Commented Nov 2, 2013 at 19:12

2 Answers 2

0

Some libraries like RSON support parsing the so-called "relaxed" JSON notation.

Depending on the actual keys, and if you don't care about the security implications (never use this on external input), eval may give you a functioning dictionary as well.

Sign up to request clarification or add additional context in comments.

2 Comments

I'd like not to use another library, and unfortunately, I can't use eval in this case (not secure!). But thank you nonetheless.
I was unable to find a solution in pure Python, so I am accepting this answer since it would fix the problem for others.
0

one simple way to do it in js:

'{num1: 1383241561141, num2: 1000}'   // the string
  .trim()                             // remove whitespace
  .slice(1,-1)                        // remove endcap braces
  .trim()                             // remove whitespace
  .split(/\s*,\s*/).map(function(a){  // loop through each comma section names as a
     var p=a.split(/\s*:\s*/);        // split section into key/val segments
     this[p[0]]=p[1];                 // assign val to collection under key
     return this;                     // return collection
},{})[0];                             // grab the return once (same on each index)

This routine returns a live object that stringifys like this:

{
    "num1": "1383241561141",
    "num2": "1000"
}

note the string numbers, you can loop through the object again and Number(val) those keys back to real numbers if need be.

4 Comments

Unfortunately, I'm forced to do this in python, but thank you for the js snippet :)
ahh, i didn't see that you need it in python... well, now that you can see a routine that works, translate it to python. i know python has the pieces you need, and it's what, 6 lines of code?
Yes, exactly. I think I have to worry about commas and colons in my val strings, though. I might be missing how those splits work in javascript (I'm new to it), but, I think they'd trip up on that, right?
@2rs2ts: well your demo data works fine with a naive approach. you could do a char-by-char parser, that's actually kinda fun and not as hard as it sounds, but i think the RegExp to JSON route is the simplest if you can get it to take...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.