【问题标题】:Python mutliline regex - Multiple Tags and ConditionsPython 多行正则表达式 - 多个标签和条件
【发布时间】:2020-11-15 14:54:40
【问题描述】:

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

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,再后面是缩进的属性。

每个条目之间有一个空行(无论MAINSUB

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 的项目以生成所描述的键值结构。

有人可以提示我一种优雅的方式来处理这种结构,实际上它定义得很好并且应该可以处理:)

干杯,谢谢大家!

【问题讨论】:

    标签: python regex multiline


    【解决方案1】:

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

    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'}]}}
    

    【讨论】:

      【解决方案2】:

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

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

      您可以看到几个从文本文件 here 填充 python 字典的示例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多