Prabhakar Shanmugam
Prabhakar Shanmugam

Reputation: 6144

Convert a string with the name of a variable to a dictionary

I have a string which is little complex in that, it has some objects embedded as values. I need to convert them to proper dict or json.

foo = '{"Source": "my source", "Input": {"User_id": 18, "some_object": this_is_a_variable_actually}}'

Notice that the last key some_object has a value which is neither a string nor an int. Hence when I do a json.loads or ast.literal_eval, I am getting malformed string errors, and so Converting a String to Dictionary doesn't work.

I have no control over the source of the string.

Is it possible to convert such strings to dictionary

The result I need is a dict like this

dict = {
        "Source" : "Good",
        "object1": variable1,
        "object2": variable2
}

The thing here is I wouldn't know what is variable1 or 2. There is no pattern here.

One point I want to mention here is that, If I can make the variables as just plain strings, that is also fine

For example,

dict = {
        "Source" : "Good",
        "object1": "variable1",
        "object2": "variable2"
}

This will be good for my purpose. Thanks for all the answers.

Upvotes: 2

Views: 1008

Answers (1)

Jon Clements
Jon Clements

Reputation: 142106

It's a bit of a kludge using the demjson module which allows you to parse most of a somewhat non-confirming JSON syntax string and lists the errors... You can then use that to replace the invalid tokens found and put quotes around it just so it parses correctly, eg:

import demjson
import re

foo = '{"Source": "my source", "Input": {"User_id": 18, "some_object": this_is_a_variable_actually}}'

def f(json_str):
    res = demjson.decode(json_str, strict=False, return_errors=True)
    if not res.errors:
        return res
    for err in res.errors:
        var = err.args[1]
        json_str = re.sub(r'\b{}\b'.format(var), '"{}"'.format(var), json_str)
    return demjson.decode(json_str, strict=False)

res = f(foo)

Gives you:

{'Input': {'User_id': 18, 'some_object': 'this_is_a_variable_actually'}, 'Source': 'my source'}

Note that while this should work in the example data presented, your mileage may vary if there's other nuisances in your input that require further munging.

Upvotes: 2

Related Questions