2013-01-21 103 views
0

我在字符串像以下类似的东西:创建从字符串,看起来像字典对象

myString = "major: 11, minor: 31, name: A=1,B=1,C=1,P=1, severity: 0, comment: this is down" 

我有这个到目前为止已经试过:

dict(elem.split(':') for elem in myString.split(',')) 

它工作正常直到它捕获到的名称元素不能是split()':'。 这些格式的元素我希望作为新的词典使用,例如

myDic = {'major':'11', 'minor': '31', 'name':{'A':'1', 'B':'1', 'C':'1', 'P', '1'}, 'severity': '0', 'comment': 'this is down'} 

如果可能的话,我想避免复杂的解析,因为这些都很难维护。 此外,我不知道上面的字符串中的键或值的名称/数量。我只知道格式。这不是JSON响应,这是文件中文本的一部分,我无法控制当前的格式。

+0

您将需要一个自定义的解析器的格式; 'name'中的'''与字符串中的其他逗号冲突。 –

+1

它看起来不像json,但是如果你对格式有任何控制,我确实建议使用json。 –

+0

@TomaszŁazarowicz你是对的,我在看字典:/ –

回答

0

这是另一个建议。

你为什么不把它转换成字典符号。

E.g.在第一步中,将包含'='(和mybe没有空格,我不知道)的':'和(逗号或输入结束)之间的所有内容替换为大括号中的'=' ':'。

在第二步中,将':'和(逗号或输入结束)之间的所有内容都包含在'中,去除尾随和前导空格。

最后,你把它全部包装在大括号中。

我还是不相信,语法,虽然...也许几千行后已成功处理...

1

仅供参考,这是不完整的解决方案..

如果是这样的混凝土结构的输入,并且将你的源代码中的常数模式,可以区分逗号分隔令牌。

major: 11之间的差异,和name: A=1,B=1,C=1,P=1,是,有所述第一令牌,这使得从所述第二令牌的差后SPACE。因此,只需在第二个split方法中添加一个空格,就可以正确渲染字符串。

所以,代码应该是这样的:

dict(elem.split(':') for elem in myString.split(', ')) 

注重送分裂法。有一个空格和逗号...

关于JSON格式,它需要更多的工作,我猜。我现在不知道..

+2

我想说这样解释给定的例子是相当勇敢的。它看起来不像是谁发明了这个语法就清楚了解这个应该如何解析,否则语法会有所不同。那么我们怎么能得出这样的结论呢? –

+0

正如在上面的评论中提到的,我不能依靠空白! – theAlse

0

至少,这正确地分析给定的例子...

import re 

def parse(s): 

    rx = r"""(?x) 
     (\w+) \s* : \s* 
     (
      (?: \w+ = \w+,)* 
      (?: \w+ = \w+) 
      | 
      (?: [^,]+) 
     ) 
    """ 

    r = {} 
    for key, val in re.findall(rx, s): 
     if '=' in val: 
      val = dict(x.split('=') for x in val.split(',')) 
     r[key] = val 
    return r 


myString = "major: 11, minor: 31, name: A=1,B=1,C=1,P=1, severity: 0, comment: this is down" 
print parse(myString)  
# {'comment': 'this is down', 'major': '11', 'name': {'A': '1', 'P': '1', 'C': '1', 'B': '1'}, 'minor': '31', 'severity': '0'}