当前位置: 动力学知识库 > 问答 > 编程问答 >

python - How we convert string into json

问题描述:

I want to convert ansible-init file into json. So, I just use this code:

common_shared file:

 [sql]

x.com

[yps_db]

y.com

[ems_db]

c.com

[scc_db]

d.com

[all:vars]

server_url="http://x.com/x"

app_host=abc.com

server_url="https://x.com"

[haproxy]

1.1.1.1 manual_hostname=abc instance_id=i-dddd

2.2.2.2 manual_hostname=xyz instance_id=i-cccc

For converting Ansible INI file in JSON:

 import json

options= {}

f = open('common_shared')

x = f.read()

config_entries = x.split()

for key,value in zip(config_entries[0::2], config_entries[1::2]):

cleaned_key = key.replace("[",'').replace("]",'')

options[cleaned_key]=value

print json.dumps(options,indent=4,ensure_ascii=False)

But it will print this result:

{

"scc_db": "xxx",

"haproxy": "x.x.x.x",

"manual_hostname=xxx": "instance_id=xx",

"ems_db": "xxx",

"yps_db": "xxx",

"all:vars": "yps_server_url=\"xxx\"",

"1.1.1.5": "manual_hostname=xxx",

"sql": "xxx",

"xxx": "scc_server_url=xxxx\""

}

But I wanted to print result in proper JSON format but not able to understand how. I tried config parser but didn't get help to print it in desired format.

网友答案:

You can use ConfigParser to read in your file, and then do the conversion to a dict to dump.

from ConfigParser import ConfigParser
from collections import defaultdict

config = ConfigParser()
config.readfp(open('/path/to/file.ini'))

def convert_to_dict(config):
    config_dict = defaultdict(dict)
    for section in config.sections():
        for key, value in config.items(section):
            config_dict[section][key] = value

    return config_dict

print convert_to_dict(config)

EDIT

As you stated in your comment, some line items are just 'things' with no value, the below might work for you.

import re
from collections import defaultdict

SECTION_HEADER_RE = re.compile('^\[.*\]$')
KEY_VALUE_RE = re.compile('^.*=.*$')

def convert_ansible_to_dict(filepath_and_name):
    ansible_dict = defaultdict(dict)
    with open(filepath_and_name) as input_file:
        section_header = None
        for line in input_file:
            if SECTION_HEADER_RE.findall(line.strip()):
                section_header = SECTION_HEADER_RE.findall(line.strip())[0]
            elif KEY_VALUE_RE.findall(line.strip()):
                if section_header:
                    # Make sure you have had a header section prior to the line
                    key, value = KEY_VALUE_RE.findall(line.strip())[0].split('=', 1)
                    ansible_dict[section_header][key] = value
            else:
                if line.strip() and section_header:
                    # As they're just attributes without value, assign the value None
                    ansible_dict[section_header][line.strip()] = None

    return ansible_dict

This is a naive approach, and might not catch all corner cases for you, but perhaps it's a step in the right direction. If you have any 'bare-attributes' prior to your first section header, they will not be included in the dictionary as it would not know where to apportion it to, and the regex for key=value pairs is working on the assumption that there will be only 1 equals sign in the line. I'm sure there might be many other cases I'm not seeing right now, but hopefully this helps.

网友答案:

Christian's answer is the correct one: Use ConfigParser. Your issue with his solution is that you have an incorrectly formatted INI file.

You need to change all your properties to:

key=value
key: value

e.g.
[sql]
aaaaaaa: true

https://wiki.python.org/moin/ConfigParserExamples

https://en.wikipedia.org/wiki/INI_file#Keys_.28properties.29

分享给朋友:
您可能感兴趣的文章:
随机阅读: