解析多层文本列表
我需要解析文本列表:
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