我正在尝试创建一个python脚本,它可以解析包含键和值的以下类型的日志条目。对于每个键,可能有也可能没有另一对嵌套的键和值。一个例子如下。嵌套的深度可以根据我得到的日志而变化,因此它必须是动态的。然而,深度用括号封装。
我将使用键和值的字符串是这样的:
Countries = {
"USA" = 0;
"Spain" = 0;
Connections = 1;
Flights = {
"KLM" = 11;
"Air America" = 15;
"Emirates" = 2;
"Delta" = 3;
};
"Belgium" = 1;
"Czech Republic" = 0;
"Netherlands" = 1;
"Hungary" = 0;
"Luxembourg" = 0;
"Italy" = 0;
};
以上数据也可以有多个巢穴。我想写一个函数来解析这个并将它放在一个数组(或类似的数组)中,这样我就可以得到一个特定键的值,如:
print countries.belgium
value should be printed as 1
同样地,
print countries.flights.delta
value should be printed as 3.
请注意,输入不需要在所有键(如连接或航班)中都有引号。
指向我可以开始的任何指示。任何已经可以像这样解析的python库了吗?
答案 0 :(得分:1)
迭代数据并检查元素是否是另一个键值对,如果是,则递归调用该函数。像这样:
def parseNestedData(data):
if isinstance(data, dict):
for k in data.keys():
parseNestedData(data.get(k))
else:
print data
输出:
>>> Countries = {
"USA" : 0,
"Spain" : 0,
"Connections" : 1,
"Flights" : {
"KLM" : 11,
"Air America" : 15,
"Emirates" : 2,
"Delta" : 3,
},
"Belgium" : 1,
"Czech Republic" : 0,
"Netherlands" : 1,
"Hungary" : 0,
"Luxembourg" : 0,
"Italy" :0
};
>>> Countries
{'Connections': 1,
'Flights': {'KLM': 11, 'Air America': 15, 'Emirates': 2, 'Delta': 3},
'Netherlands': 1,
'Italy': 0,
'Czech Republic': 0,
'USA': 0,
'Belgium': 1,
'Hungary': 0,
'Luxembourg': 0, 'Spain': 0}
>>> parseNestedData(Countries)
1
11
15
2
3
1
0
0
0
1
0
0
0
答案 1 :(得分:1)
我已经创建了一个示例python脚本来完成这项工作,只需按照您的喜好进行调整即可。它将您的格式转换为嵌套的dict。它和你一样充满活力。
请看这里:Paste bin 代码:
import re
import ast
data = """ { Countries = { USA = 1; "Connections" = { "1 Flights" = 0; "10 Flights" = 0; "11 Flights" = 0; "12 Flights" = 0; "13 Flights" = 0; "14 Flights" = 0; "15 Flights" = 0; "16 Flights" = 0; "17 Flights" = 0; "18 Flights" = 0; "More than 25 Flights" = 0; }; "Single Connections" = 0; "No Connections" = 0; "Delayed" = 0; "Technical Fault" = 0; "Others" = 0; }; }"""
def arrify(string):
string = string.replace("=", " : ")
string = string.replace(";", " , ")
string = string.replace("\"", "")
stringDict = string.split()
# print stringDict
newArr = []
quoteCosed = True
for i, splitStr in enumerate(stringDict):
if i > 0:
# print newArr
if not isDelim(splitStr):
if isDelim(newArr[i-1]) and quoteCosed:
splitStr = "\"" + splitStr
quoteCosed = False
if isDelim(stringDict[i+1]) and not quoteCosed:
splitStr += "\""
quoteCosed = True
newArr.append(splitStr)
newString = " ".join(newArr)
newDict = ast.literal_eval(newString)
return normalizeDict(newDict)
def isDelim(string):
return str(string) in "{:,}"
def normalizeDict(dic):
for key, value in dic.items():
if type(value) is dict:
dic[key] = normalizeDict(value)
continue
dic[key] = normalize(value)
return dic
def normalize(string):
try:
return int(string)
except:
return string
print arrify(data)
示例数据的结果:
{'Countries': {'USA': 1, 'Technical Fault': 0, 'No Connections': 0, 'Delayed': 0, 'Connections': {'17 Flights': 0, '10 Flights': 0, '11 Flights': 0, 'More than 25 Flights': 0, '14 Flights': 0, '15 Flights': 0, '12 Flights': 0, '18 Flights': 0, '16 Flights': 0, '1 Flights': 0, '13 Flights': 0}, 'Single Connections': 0, 'Others': 0}}
你可以获得像普通字典那样的价值:)希望它有帮助...
答案 2 :(得分:1)
定义一个处理和存储信息的类结构,可以给你这样的东西:
import re
class datastruct():
def __init__(self,data_in):
flights = re.findall('(?:Flights\s=\s*\{)([\s"A-Z=0-9;a-z]*)};',data_in)
flight_dict = {}
for flight in flights[0].split(';')[0:-1]:
key,val = self.split_data(flight)
flight_dict[key] = val
countries = re.findall('("[A-Za-z]+\s?[A-Za-z]*"\s=\s[0-9]{1,2})',data_in)
countries_dict = {}
for country in countries:
key,val = self.split_data(country)
if key not in flight_dict:
countries_dict[key]=val
connections = re.findall('(?:Connections\s=\s)([0-9]*);',data_in)
self.country= countries_dict
self.flight = flight_dict
self.connections = int(connections[0])
def split_data(self,data2):
item = data2.split('=')
key = item[0].strip().strip('"')
val = int(item[1].strip())
return key,val
请注意,如果数据不完全如我在下面假设的那样,可能需要调整正则表达式。可以如下设置和引用数据:
raw_data = 'Countries = { "USA" = 0; "Spain" = 0; Connections = 1; Flights = { "KLM" = 11; "Air America" = 15; "Emirates" = 2; "Delta" = 3; }; "Belgium" = 1; "Czech Republic" = 0; "Netherlands" = 1; "Hungary" = 0; "Luxembourg" = 0; "Italy" = 0;};'
flight_data = datastruct(raw_data)
print("No. Connections:",flight_data.connections)
print("Country 'USA':",flight_data.country['USA'],'\n'
print("Flight 'KLM':",flight_data.flight['KLM'],'\n')
for country in flight_data.country.keys():
print("Country: {0} -> {1}".format(country,flight_data.country[country]))