所以我有一个类似于JSON格式的键值文件,但它与Python JSON解析器无法接受。
示例:
"Matt"
{
"Location" "New York"
"Age" "22"
"Items"
{
"Banana" "2"
"Apple" "5"
"Cat" "1"
}
}
有没有简单的方法来解析这个文本文件并将值存储到一个数组中,以便我可以使用类似于Matt [Items] [Banana]的格式访问数据?每条线只有一对,一个支架应该表示下降到一个水平并上升到一个水平。
答案 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'])