Python解析复杂的命令输出

时间:2013-05-17 01:00:59

标签: python parsing

需要在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秒运行一次命令,并确定变化内容的差异

2 个答案:

答案 0 :(得分: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非常简单。

答案 1 :(得分:0)

这应该有一个'parsing'标签,因为它是一般的解析问题。

在这种情况下的正常解决方案是跟踪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]包含已解析的文档。