首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python:解析文本文件并创建树结构

Python:解析文本文件并创建树结构
EN

Stack Overflow用户
提问于 2015-09-07 01:50:40
回答 2查看 1.7K关注 0票数 2

解析像这样的纯文本树结构的最佳方法是什么:

代码语言:javascript
复制
node1:
    node1
    node2:
        node1
node2:
    node1
    node2
    node3:
        node1:
            node1
        node2:
            node1
            node2

并将其转换为树形结构(带有列表或字典)?

有没有python库可以帮我解析?

EN

回答 2

Stack Overflow用户

发布于 2015-09-07 01:55:03

rson库可以做到这一点,除非您可能必须对解析器进行子类化,以允许在单个结构中混合使用数组和字典样式的元素。

编辑实际上,这可能有点困难,但rsonlite包将(某种程度上)对您的数据按原样工作。

rsonlite是一个小的、单模块的包,只有300行,相同的源代码适用于Python2和Python3。

下面是一个示例,它显示了数据的3种不同输出。第一个输出是rsonlite.dumps()提供的内容,第二个输出是稍高级别的rsonlite.simpleparse()提供的内容,第三个输出从simpleparse获取结果并通过自定义fixup()函数运行它们,以创建一个纯嵌套字典数据结构,其中任何缺少的值都被简单地设置为None,并且检查并剥离所有冒号字符。

代码语言:javascript
复制
from rsonlite import loads, simpleparse


mystring = '''
node1:
    node1
    node2:
        node1
node2:
    node1
    node2
    node3:
        node1:
            node1
        node2:
            node1
            node2
'''

def fixup(node):
    if isinstance(node, str):
        return node
    elif isinstance(node, dict):
        for key in node:
            assert key.endswith(':'), key
        return dict((key[:-1], fixup(value)) for key, value in node.items())
    else:
        assert isinstance(node, (list, str))
        result = {}
        for item in node:
            if isinstance(item, str):
                assert not item.endswith(':')
                assert result.setdefault(item, None) is None
            else:
                for key, value in fixup(item).items():
                    assert result.setdefault(key, value) is value
        return result

print('')
print(loads(mystring))
print('')
print(simpleparse(mystring))
print('')
print(fixup(simpleparse(mystring)))
print('')

将给予:

[('node1:',['node1',('node2:','node1')]),('node2:',['node1','node2',('node3:',[('node1:','node1'),('node2:','node1',‘node2’)])]

OrderedDict([('node1:',['node1',OrderedDict(('node2:',‘node1’))],('node2:',['node1','node2',OrderedDict([('node3:','node1'),('node2:','node1',‘node2’))])

{'node1':无,'node2':'node1'},'node2':{'node1':无,'node2':无,'node3':{'node1':'node1','node2':{'node1':无,'node2':无}

票数 4
EN

Stack Overflow用户

发布于 2015-09-07 06:45:02

您可以构造一个简单的解析器,该解析器从输入生成有效的python表达式,然后对其求值。我最初的想法是一个简单的递归解析器,但这比我预期的要困难得多,因为他们没有办法知道块是在没有峰值的情况下结束的-这是基于缩进的格式的常见问题。

这将生成元组(block_name、contents)的嵌套列表:

代码语言:javascript
复制
i = 0
r = '['
for l in mystring.split('\n'):
    if not l:
        continue
    cl = l.lstrip(' ')
    ci = (len(l) - len(cl))//4
    if ci > i:           # line indented
        r += '['
    elif ci < i:         # line unindented, can be multiple
        r += '])'*(i-ci) + ','
    if cl[-1] == ':':    # new block
        r += '{("{}":'.format(cl[:-1])
    else:                # new item
        r += '"{}",'.format(cl)
    i = ci
r += ']'+')]'*i
eval(r)

输出:

代码语言:javascript
复制
[('node1', ['node1', ('node2', ['node1'])]),
 ('node2',
  ['node1',
   'node2',
   ('node3', [('node1', ['node1']), ('node2', ['node1', 'node2'])])])]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32426522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档