Python 多行正则表达式 - 多个标签和条件

Python mutliline regex - Multiple Tags and Conditions

我不得不承认,我的 Regex 质量很差,我(在这种情况下)通过其他解决方案避免了它们。但是,在这种情况下,为了稳定和清洁,我真的很想有一个解决方案。 输入文件看起来如下:

MAIN: name
  attr1: str
  attr2: str
  attr3: str

SUB: name
  attr1: str
  attr2: str
  attr3: str

MAIN: name
  attr1: str
  attr2: str

SUB: name
  attr1: str
  attr2: str

SUB: name
  attr1: str

SUB: name
  attr1: str
  attr2: str
  attr3: str

条目始终以未缩进的 MAIN 开头,后跟 collonname

以下是 1 to N 个缩进键值对。

然后有 0 to N 个未缩进的条目 SUB:name,然后是缩进的属性。

每个条目之间有一个空行(无论MAIN还是SUB

Output应该如下

output = {main_name:
             {
               'attr1': str,
               'attr2': str,
               ...
               'subs': [
                          {
                              'name': sub_name,
                              'attr1': str,
                              ...
                          },
                          {...}
                       ]
             }

          main_name2: 
             {
              ...
             }
          }

我目前的做法是这样的:

entries = input.split('\n\n')
entries = [entry.replace(" ","").split("\n") for entry in entries]
entries = [attribute.split(":") for entry in entries for attribute in entry]          

然后使用大量 if 和 else 遍历项目以生成所描述的键值结构。

有人可以提示我一种优雅的方式来处理这样的结构,实际上定义非常明确并且应该可以处理:)

干杯,谢谢你们!

对于这样的结构,老实说,我不会直接使用正则表达式来读取文件。数据结构看起来像嵌套的 dictionary.

如何创建一个字典对象并在读取文件时填充键、子字典和子键?

您可以看到几个从文本文件 here.

填充 python 词典的示例

您可以逐行迭代,一边构建结构。您只需要跟踪您当前的位置,以便将属性放在它们所属的位置:

def parse_data(data):
    out = {}
    for line in data.splitlines():
        if not line:
            continue
        if line.startswith("MAIN"):
            name = line[6:]
            out[name] = {}
            current = out[name]
        elif line.startswith("SUB"):
            subname = line[5:]
            out[name].setdefault('subs', []).append({'name': subname})
            current = out[name]['subs'][-1]
        elif line.startswith('  '):
            attr, value = line[2:].split(':')
            value = value.strip()
            current[attr] = value
            
    return out


data = """
MAIN: main1
  attr1: str
  attr2: str
  attr3: str
​
SUB: 1.1
  attr1: str
  attr2: str
  attr3: str
​
MAIN: main2
  attr1: str
  attr2: str
​
SUB: 2.1
  attr1: str
  attr2: str
​
SUB: 2.2
  attr1: str
​
SUB: 2.3
  attr1: str
  attr2: str
  attr3: str
"""

输出:

​
print(parse_data(data))


{'main1': {'attr1': 'str',
  'attr2': 'str',
  'attr3': 'str',
  'subs': [{'name': '1.1', 'attr1': 'str', 'attr2': 'str', 'attr3': 'str'}]},
 'main2': {'attr1': 'str',
  'attr2': 'str',
  'subs': [{'name': '2.1', 'attr1': 'str', 'attr2': 'str'},
   {'name': '2.2', 'attr1': 'str'},
   {'name': '2.3', 'attr1': 'str', 'attr2': 'str', 'attr3': 'str'}]}}