首页 > 解决方案 > 将空格分隔的键值块上的 Python 正则表达式到字典列表

问题描述

我有由空格分隔并使用 ==== 字符分成块的键值字符串的大多行文本。对于每个块,我想创建一个带有键值的字典

基本上,我发现自己在编写正则表达式而不是创建字典时更加努力,我用它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 of name, value= value of projects 生成字典的正则表达式,例如:

{jcento: 'proj1 proj2 proj3 proj4', jcento5: 'proj1 proj2 proj3 proj4'}.

提前致谢!

标签: pythonregexdictionaryparsing

解决方案


如果我理解正确,您希望由“===========”边界分隔的每个部分成为其在字典列表中的唯一字典。您没有提供任何代码,但看到您使用此正则表达式来查找键/值对

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-blocks 中,以检查是否有任何数据点与您的正则表达式模式不匹配


推荐阅读