2016-09-12 28 views
-1

我有一個應用程序產生一個奇怪的配置文件的Python解析一個醜陋的配置文件

app_id1 { 
key1 = val 
key2 = val 
... 
} 
app_id2 { 
key1 = val 
key2 = val 
... 
} 
... 

而且我掙扎如何在python解析此。每個應用程序的鍵可能會有所不同。 我不能改變應用程序來生成配置文件在一些易於解析的格式:)

任何建議如何做到這一點pythonically? 我沿着字典的字典的思路思考

conf = {'app_id1': {'key1' : 'val', 'key2' : 'val'}, 
     'app_id2' : {'key1' : 'val', 'key2' : 'val'} 
     } 
+0

這似乎有很多相似的無論如何,只有在每行末尾加上'\ n'。 – Flippym

+0

是的,你可以把它讀入你的文件,然後用':'替換'=',然後瞧,你有一本字典。 –

回答

2

嘗試是這樣的:

我假定你讀文件的內容爲字符串

config_file_string = '''app_id1 { 
key1 = val 
key2 = val 
key3 = val 
} 
app_id2 { 
key1 = val 
key2 = val 
}''' 

config = {} 
appid = '' 
for line in config_file_string.splitlines(): 
    print(line) 
    if line.endswith('{'): 
     appid = line.split()[0].strip() 
     placeholder_dict = {} 
    elif line.startswith('}'): 
     config[appid] = placeholder_dict 
    else: 
     placeholder_dict[line.split('=')[0].strip()] = line.split('=')[1].strip() 

print(config) 

這將返回:

{'app_id2': {'key2 ': ' val', 'key1 ': ' val'}, 'app_id1': {'key3 ': ' val', 'key2 ': ' val', 'key1 ': ' val'}} 
+0

我正在用類似的東西:)。謝謝 – mittal

2

你可以使用正則表達式:(\w+)\s*\{([^}]*)將找到一個name { values }結構,而([^\s=]+)\s*=\s*([^\n]*)將找到key = value對。

作爲一個內膽,假設該文件的內容在變s

config= {key:dict(re.findall(r'([^\s=]+)\s*=\s*([^\n]*)', values)) for key,values in re.findall(r'(\w+)\s*\{([^}]*)', s)} 
+0

它的眼睛好難看流血!我喜歡它,有我的祝福! –

+0

@饒舌啊,是的!這真是太難看了:)。你能幫我理解一下嗎?我嚼了一些像 - \ w,\ s * \ {和[^}]。但不是爲什麼用\ w和()使用() – mittal

+0

@mittal:'+'使它捕獲多於一個字符,而不是它只會匹配'key'的最後一個字符。圓括號使得匹配的文本被捕獲並返回。 –

2

可以使用pyparsing少嚴格的語法:

from pyparsing import alphanums, restOfLine, OneOrMore, Word, Suppress 
from copy import copy 
lbrace,rbrace,eq = map(Suppress,"{}=") 

configitem = {} 
configall = {} 

wd = Word(alphanums+'_') 
kw = wd + eq + restOfLine 
kw.setParseAction(lambda x: configitem.__setitem__(x[0],x[1].strip())) 
group = wd + lbrace + OneOrMore(kw) + rbrace 
group.addParseAction(lambda x: configall.__setitem__(x[0],copy(configitem))) 
group.addParseAction(lambda x: configitem.clear()) 

config = OneOrMore(group) 


config_file_string = '''app_id1 
{ 
key1 = val 
key2 = val 

key3 = val 
} 


app_id2 { 
key1 = val 

key2 = val 

}''' 

config.parseString(config_file_string) 
print(configall)