【问题标题】:Parsing multilevel text list解析多级文本列表
【发布时间】:2009-12-11 01:36:38
【问题描述】:

我需要解析文本列表:

1 List name

1 item
2 item
3 item

2 List name

1 item
2 item
3 item

3 List name

1 item
2 item
3 item

我正在尝试使用正则表达式来拆分第一级列表:

import re
def re_show(pat, s):
 print re.compile(pat, re.S).sub("{\g<0>}", s),'\n'

s = '''
1 List name

1 item
2 item
3 item

2 List name

1 item
2 item
3 item

3 List name

1 item
2 item
3 item
'''

re_show('\n\d+.*?(?=\n\n\d+.*?\n\n)', s)

但它不起作用。而不是这个:

{
1 List name

1 item
2 item
3 item}
{
2 List name

1 item
2 item
3 item}
{
3 List name

1 item
2 item
3 item}

我有这个:

{
1 List name}
{
1 item
2 item
3 item}
{
2 List name}
{
1 item
2 item
3 item}

3 List name

1 item
2 item
3 item

你会推荐什么来解决这个任务?

感谢您的回答。我学到了 Python 的许多新特性。

我想,我会使用here所描述的“状态机”方法

【问题讨论】:

    标签: python regex parsing


    【解决方案1】:

    您可以控制列表格式吗?只需稍加编辑,您就可以将其转换为配置文件格式,并使用 ConfigParser 模块。

    否则,用一点递归怎么样?

    from collections import defaultdict
    
    def fill_data(data, key, sequence, pred):
        """Recursively fill the data dictionary"""
        for item in sequence:
            # if the pred is true, add it to the list
            if pred(item):
                data[key].append(item)
            # otherwise recurse, with item as key
            else:
                return fill_data(data, item, sequence, pred)
        return data
    
    # a key->list dictionary
    data = defaultdict(list)
    # Get the text as a sequence of non-empty lines
    lines = (l for l in s.splitlines() if l.strip())
    
    def is_data_line(line):
        """Is this line a data line (i.e. two items)?"""
        return len(line.split()) == 2
    
    result = fill_data(data, None, lines, is_data_line )
    
    print dict(result)
    

    输出(美化)

    {'2 List name': 
        ['1 item', '2 item', '3 item'], 
     '3 List name': 
        ['1 item', '2 item', '3 item'], 
     '1 List name': 
        ['1 item', '2 item', '3 item']}
    

    【讨论】:

    • 不,我没有。我需要将这种格式转换为另一种格式(列表很长,这只是一个小例子)你的代码运行良好,但我还不明白(我是新手:))谢谢!
    • 你说得对,代码有点神秘。感谢您指出。我添加了一些 cmets,我希望它们能让它的功能更加清晰。
    【解决方案2】:
    class ListParser:
    
     def __init__(self, s):
      self.str = s.split("\n")
      print self.str
      self.answer = []
    
     def parse(self):
      self.nextLine()
      self.topList()
      return
    
     def topList(self):
      while(len(self.str) > 0):
       self.topListItem()
    
     def topListItem(self):
      l = self.nextLine()
      print "TOP: " + l
      l = self.nextLine()
      if l != '':
       raise Exception("expected blank line but found '%s'" % l)
      sub = self.sublist()
    
     def nextLine(self):
      return self.str.pop(0)
    
     def sublist(self):
      while True:
       l = self.nextLine()
       if l == '':
        return # end of sublist marked by blank line
       else:
        print "SUB: " + l
    
    parser = ListParser(s)
    parser.parse() 
    print "done"
    

    打印

    TOP: 1 List name
    SUB: 1 item
    SUB: 2 item
    SUB: 3 item
    TOP: 2 List name
    SUB: 1 item
    SUB: 2 item
    SUB: 3 item
    TOP: 3 List name
    SUB: 1 item
    SUB: 2 item
    SUB: 3 item
    done
    

    【讨论】:

    • 您的解决方案让我想到了使用“状态机”方法的想法。谢谢。
    【解决方案3】:

    这是使用字典的一种方法

    f=open("myfile")
    d={}
    e=0
    for line in f:
        line=line.rstrip()
        if "List" in line:
          e=e+1
          d.setdefault(e,[])
        d[e].append(line)
    f.close()
    for i ,j in d.iteritems():
        print i,j
    

    【讨论】:

    • 谢谢!我是 Python 的新手。我不知道字典。非常类似于关联数组。
    【解决方案4】:

    我怀疑我没有抓住重点,但这不只是寻找List的问题吗?

    【讨论】:

    • 不,“列表名称”可以是任何字符串
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多