解析多层文本列表

0 投票
4 回答
603 浏览
提问于 2025-04-15 16:54

我需要解析文本列表:

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特性。

我想我会使用“状态机”的方法,正如这里所描述的那样。

4 个回答

1

这里有一种使用字典的方法

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
2

你能控制列表的格式吗?只需稍微编辑一下,你就可以把它变成配置文件的格式,然后使用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']}
1
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

撰写回答