在Python中解析键值对

时间:2015-10-11 23:41:38

标签: python parsing

所以我有一个类似于JSON格式的键值文件,但它与Python JSON解析器无法接受。

示例:

"Matt"
{
    "Location"    "New York"
    "Age"         "22"
    "Items"
    {
        "Banana"    "2"
        "Apple"     "5"
        "Cat"       "1"
    }
}

有没有简单的方法来解析这个文本文件并将值存储到一个数组中,以便我可以使用类似于Matt [Items] [Banana]的格式访问数据?每条线只有一对,一个支架应该表示下降到一个水平并上升到一个水平。

2 个答案:

答案 0 :(得分:3)

您可以使用re.sub来修复'你的字符串,然后解析它。只要格式在每行上始终是单引号字符串或一对带引号的字符串,您就可以使用它来确定逗号和冒号的放置位置。

import re
s = """"Matt"
{
    "Location"    "New York"
    "Age"         "22"
    "Items"
    {
        "Banana"    "2"
        "Apple"     "5"
        "Cat"       "1"
    }
}"""

# Put a colon after the first string in every line
s1 = re.sub(r'^\s*(".+?")', r'\1:', s, flags=re.MULTILINE)
# add a comma if the last non-whitespace character in a line is " or }
s2 = re.sub(r'(["}])\s*$', r'\1,', s1, flags=re.MULTILINE)

完成上述操作后,您可以使用ast.literal_eval将其转换为Python字典。我通过JSON解析使用它,因为它允许使用尾随逗号,没有这些逗号,将逗号放在哪里的决定变得更加复杂:

import ast
data = ast.literal_eval('{' + s2 + '}')
print data['Matt']['Items']['Banana']
# 2

答案 1 :(得分:0)

不确定此方法在您发布的示例之外是多么强大,但它确实支持转义字符和更深层次的结构化数据。对于大量数据来说,它可能不够快。

该方法使用(非常)简单的解析器将您的自定义数据格式转换为JSON,以添加所需的冒号和大括号,然后可以将JSON数据转换为本机Python字典。

import json

# Define the data that needs to be parsed
data = '''
"Matt"
{
    "Location"    "New \\"York"
    "Age"         "22"
    "Items"
    {
        "Banana"    "2"
        "Apple"     "5"
        "Cat"
        {
            "foo"   "bar"
        }
    }
}
'''

# Convert the data from custom format to JSON
json_data = ''

# Define parser states
state = 'OUT'
key_or_value = 'KEY'

for c in data:
    # Handle quote characters
    if c == '"':
        json_data += c

        if state == 'IN':
            state = 'OUT'
            if key_or_value == 'KEY':
                key_or_value = 'VALUE'
                json_data += ':'

            elif key_or_value == 'VALUE':
                key_or_value = 'KEY'
                json_data += ','

        else:
            state = 'IN'

    # Handle braces
    elif c == '{':
        if state == 'OUT':
            key_or_value = 'KEY'
        json_data += c

    elif c == '}':
        # Strip trailing comma and add closing brace and comma
        json_data = json_data.rstrip().rstrip(',') + '},'

    # Handle escaped characters
    elif c == '\\':
        state = 'ESCAPED'
        json_data += c

    else:
        json_data += c

# Strip trailing comma
json_data = json_data.rstrip().rstrip(',')

# Wrap the data in braces to form a dictionary
json_data = '{' + json_data + '}'

# Convert from JSON to the native Python
converted_data = json.loads(json_data)

print(converted_data['Matt']['Items']['Banana'])