我有大型的键值字符串多行文本,用空格分隔并使用====字符将其分成多个块。 对于每个块,我想创建一个具有键值的字典
基本上,我发现自己在编写正则表达式而不是在创建字典方面更加费劲,我使用r'^(\w+)\s*(.*)'
来获取键和值,就像空格之后出现的一样,但是我不知道如何将文本分成用====阻止。
值显然是伪造的,但是,每个值都可能溢出到新行,如下所示。
请参见以下文本:
name jcento
server_param uptime=2,load=2, \
mem=1,io=10
info_values cpu=5,io=1,load=0, \
core=8, mem=22724, \
info_value1 10
info_value2 banana
info_value3 NONE
projects proj1 proj2 proj3 \
proj4
info_value5 NONE
info_value6 NONE
info_value7 NONE
info_value8 NONE
info_value9 NONE
================================================================================
name jcento
server_param uptime=2,load=2, \
mem=1,io=10
info_values cpu=5,io=10,load=0, \
core=8, mem=22724, \
info_value1 10
info_value2 banana
info_value3 NONE
projects proj1 proj2 proj3 \
proj4
info_value5 NONE
info_value6 NONE
info_value7 NONE
info_value8 NONE
info_value9 NONE
我希望输出为字典[{name:'jcento', server_param: 'uptime=2,load=2,mem=1,io=1', ...}, {name:'jcento5',....}]
如果可能的话,还可以创建一个正则表达式,以根据名称的key = value值,project = value的值生成一个字典,例如:
{jcento: 'proj1 proj2 proj3 proj4', jcento5: 'proj1 proj2 proj3 proj4'}
。
谢谢!
答案 0 :(得分:0)
如果我对您的理解是正确的,那么您希望将以“ ============”边界分隔的每个部分作为其在词典列表中的唯一词典。 您没有提供任何代码,但是看到您使用此正则表达式来查找键/值对
r'^(\w+)\s*(.*)'
我假设您抓住了这两个组并将它们各自的值简单地传递为newDict[match.group(1)] = match.group(2)
问题归结于您如何读取数据。用这种方法,我只需要逐行读取文件,但是由于您的值可以是多行的,因此我已经不确定如何从提供的正则表达式中获得正确的分组。 “(。*)”应该像地狱般贪婪,并且比您想要的回报更多。
如果所有行跳转都标有“ \”,则可以编写一个正则表达式,将其考虑在内,如下所示: 将“(。*)”替换为“([[\ w,=] +(\ s \\ s?[\ w,=] +)?)”
但是,我可能会在阅读文本文件时对文本文件进行某些调整,以将所有数据点存储在一行上,然后遍历该文本点并使用您以前的正则表达式捕获。 增加的奖励: 您可以在迭代函数中添加与“ ==========”匹配的行,并在将旧字典添加到列表的同时初始化新字典。
import re
final_list = []
def makeDict(fl, data):
kvPattern = re.compile(r'^(\w+)\s*(.*)')
newDict = {}
for line in data:
if line.startswith("============="):
fl.append(newDict)
newDict = {}
elif kvPattern.search(line):
match = kvPattern.search(line)
newDict[match.group(1)] = match.group(2)
return fl
final_list = makeDict(final_list, data)
如果您感到自大,也可以使用“ else”代替“ elif”。 甚至更好的是,将整个内容包装在Try块中以检查是否有任何数据点与您的正则表达式模式不匹配