如何从 Python 中的字符串解析树?

How to parse a tree from a string in Python?

我的大学笔记格式如下:

CourseName: {
    Part 1: {
        I.I - Intro: {
            Topic1: {
                descr1;
                descr2: {
                    2.a;
                    2.b;
                    2.c.
                };
                descr3.
            };
            Topic2: {
                descr: {
                    example.
                }.
            }.
        };
        I.II - NextChapter: {
            Topic3: {
                whatever.
            }.
        }.
    };
    Part 2: {
        II.I - FinalChapter: {
            content.
        }.
    }.
}

我想将它们构造成树数据结构,我已经尝试这样做,递归地和迭代地,在过去的几个小时里,我在网上做了很多研究,但是 none 我的尝试都奏效了。

我已经实现了一个 Node class(带有 self.__value 和一个列表 self.__children 以及您期望的所有有用方法从它)以及 Tree classself.__nodes 作为 dictionary 和其他实用方法),所以您可以在回答中随意使用 add_nodeadd_child 等方法。

我正在努力了解如何构建函数 def parseTree(s, l) - 理想情况下将字符串 s (我的笔记)和列表 l 作为输入分隔符,即 [":{", ";", "}."]["{","}"] 或类似的 - 和 returns 一个树对象,每个节点的值都是 :{ 之前的文本和一个子列表(如果有)文中用;分隔。

有什么建议吗?

这实际上是语法上几乎有效的 YAML。一个简单的替换将使其有效:

data = data.replace(';', ',').replace('.', '')
parsed = yaml.load(data)

假设你的数据存储在一个文件中,你可以构建一个简单的class来将结构解析成字典。您可以通过为找到的每个键创建一个新的 Notes 对象来递归遍历数据:

file_data = filter(None, [i.strip('\n') for i in open('filename.txt')])
import re
class Notes:
   def __init__(self, token_data):
     self.token_data = token_data
     self.current_dict = {}
     self.current_vals = []
     self.parse()
   def parse(self):
     while True:
       start = next(self.token_data, None)
       if not start or "}" in start:
         break
       if start.endswith('{'):
          note = Notes(self.token_data)
          final_result = filter(lambda x:x, note.current_vals + [note.current_dict]) if note.current_vals else note.current_dict
          self.current_dict[re.findall('[\w\s\-\.]+', re.sub('^\s+', '', start))[0]] = final_result[0] if isinstance(final_result, list) and len(final_result) == 1 else final_result
          self.token_data = note.token_data
       else:
          self.current_vals.append(re.sub('^\s+', '', start))


course_notes = Notes(iter(file_data)).current_dict

输出:

{'CourseName': 
    {'Part 1': 
      {'I.I - Intro': 
         {'Topic1': ['descr1;',
                    'descr3.',
             {'descr2': ['2.a;',
                         '2.b;',
                          '2.c.']
                }
               ],
         'Topic2': {'descr': 'example.'}
                 },
                  'I.II - NextChapter': 
               {'Topic3': 'whatever.'}
             },
       'Part 2':{'II.I - FinalChapter': 'content.'}
     } 
   }