2013-05-17 77 views
0

需要解析python中的命令输出。该命令返回类似这样Python解析复杂命令输出

A: 
     2 bs found 
     3 cs found 
B: 
     1 a found 
     3 bs found 
C: 
     1 c found 
     D: 
       2 es found 
       3 fs found 

极品能够做到与输出如下:

访问a.bs发现b.a发现。找到c.d.es等等。

我该如何做这个python?什么数据结构最适合这样做?

这个练习的目标是要运行的命令每10秒,并确定一个什么样的改变

+0

我该如何做一个代码块内的问题?我的命令的输出格式都是错位的。 – user2322491

+0

您可以选择代码块可以按'ctrl + k'。 – satoru

+1

澄清 - 实际上是你的输出的一部分,还是试图使它成为代码块? –

回答

0

这应该有一个“解析”的标签,因为它是一个一般的解析问题差异。

这种情况下的正常解决方案是跟踪a)缩进和b)当前正在解析的结构列表,如同你在行中读取的一样。 b将以包含单个空字典的列表开始,即。 curparsing = [{}]

遍历所有输入行。例如:

with open('inputfilename','r') as f: 
    for line in f: 
     # code implementing the below rules. 
  • 如果行是空的(if not line.strip():),忽略它,去到下一个(continue

  • 如果缩进级别有所降低,我们应该去掉顶部当前解析列表中的项目(即curparsing.pop())。如果检测到多个减少,我们应该从顶部删除多个项目。

  • 去掉所有领先的压痕与line=line.lstrip()

  • 如果“:”在该线路,那么,我们已经找到了一个子字典。阅读关键字(':'左侧的部分),增加缩进级别,创建一个新字典,并将其插入列表当前顶部的字典中。然后将我们新创建的词典附加到列表中。

  • if line[0] in '123456789':然后我们找到了'[count] [character] s found'的报告。 我们可以用正则表达式来找到计数和字符,用m = re.match('([1-9]+) ([a-z])'); count, character = m.groups(); count = int(count)。然后,我们将它存储到当前列表的最上面的字典中:curparsing[-1][character] = count

就是这样。您只需循环遍线并将这些规则应用于每行,最后,curparsing[0]包含解析的文档。

+0

感谢您的指示。会试着让你知道它是如何发生的 – user2322491

2

另一种解决方案是将输入字符串直接转换为预先存在的库可以读取的内容。这个特定的数据看起来非常适合YAML。

在这种情况下,您应该使用re.sub('(+)([1-9]+) ([a-z]).+', '\\1\\3 : \\2', allcontent),它将'2 cs found'类型行重写为pyYAML能够理解的键值映射。准确地说,'2 cs found'的格式变成'c:2'

结果?

A: 
     b : 2 
     c : 3 
B: 
     a : 1 
     b : 3 
C: 
     c : 1 
     D: 
       e : 2 
       f : 3 

执行yaml.load(newcontent)返回以下Python数据结构:

{'A': {'b': 2, 'c': 3}, 
'B': {'a': 1, 'b': 3}, 
'C': {'D': {'e': 2, 'f': 3}, 'c': 1}} 

其中我的建议,我先前的评论一致。 如果你更喜欢json(Python带有一个json模块),使用这个策略来生成JSON相当简单。