0

I have a JSON file that was filtered and lost the original structure. Each line of the file looks like this:

{u'spec1': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property3': u'98754', u'property4': u'val1'}}

json.loads doesn't work and ast.literal_eval doesn't work. I guess I have 2 issues: remove unicode and change ' to ". Can anyone provide some pointers on where to start?

2
  • ast.literal_eval works: ideone.com/skIcxY Commented Jul 29, 2015 at 8:07
  • What version of python are you using? I had Python 3.2 and it failed but updating to Python 3.4 works. Python 2.7 also works. Commented Jul 29, 2015 at 8:25

3 Answers 3

1

Assuming you are using Python 2.X.

json.loads takes a str or unicode as its param. The string you give is not a valid json string. So we should do some pre-cooking work.

import re, json

json_str = """{u'spec1': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property3': u'98754', u'property4': u'val1'}}"""
json_str = json_str.replace("\'", "\"")
json_str = re.sub(r"u\"", "\"", json_str)

json_dict = json.loads(json_str)

Then the json_dict will be a dictionary inflated from your json string.

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

7 Comments

{u'spec1': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property3': u'98754', u'property4': u'val1'}} is what I get as a result
@user20150316 result of which step?
print json_dict. json_str looks OK. But json_dict has u'
All this precooking seems a little tedious. What we are having here is a perfectly working Python objects, so why not try to eval them as such, without all that JSON magic?
Well we could use ast.literal_eval which is a little more stable. Don't get me wrong I think every solution is right as far as it does the job and makes OP happy. I just wanted to note, that there are a bit more elegant ways to do that (an I don't mean mine specifically). Anyways, this discussion has probably run its course. Have a nice day.
|
1

Here is my take (Python 2.7).

import StringIO
import ast
file = u"""{u'spec1': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property3': u'98754', u'property4': u'val1'}}
{u'spec2': {u'property1': u'12345', u'property2': 1234}, u'spec3': {u'property3': u'98754', u'property4': u'val1'}}
{u'spec4': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property5': u'98754', u'property4': u'val1'}}
{u'spec6': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property7': u'98754', u'property4': u'val1'}}
"""
buffer = StringIO.StringIO(file)
lines = buffer.readlines()
dicts = []
for line in lines:
    dicts.append(ast.literal_eval(line))
print dicts

Don't look at StringIO, it's there to emulate file-reading. What I'm proposing is to read the file by line and do literal_eval by line.

For me it was the only way to make it work without errors.

Comments

1

Looks like this works (in Python3):

$ python3.4
Python 3.4.0 (default, Jun 19 2015, 14:20:21) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> j = """{u'spec1': {u'property1': u'12345', u'property2': 1234}, u'spec2': {u'property3': u'98754', u'property4': u'val1'}}"""
>>> json.loads(j.replace("'","\"").replace('u"','"'))
{'spec1': {'property1': '12345', 'property2': 1234}, 'spec2': {'property4': 'val1', 'property3': '98754'}}

As you can see, I've replaced both ' to " chars, and (thus came) u" to " patterns.

Hope this helps.

a.

3 Comments

I am using Python 2.7 and the output still has u'
Of course, this works in Python 2(.7 and below), I just wrote the Python 3, cause' somebody wrote, he uses Python 3, and something is wrong at there. :)
@user20150316: yes, in Python 3, the default encoding of all string is unicode, therefore there isn't any prefix to show, the string is unicode (with "u'"). In Python 2, there isn't, therefore it must be show the prefix, if string is unicode. See: wiki.python.org/moin/Python2orPython3 "The most drastic improvement is the better Unicode support (with all text strings being Unicode by default)..."

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.