我知道我已经看到了一个很好的算法,但找不到它。
我从一个需要解析的工具(我无法控制的输出样式)输出(格式不佳)。
它看起来像这样:
NameOfItemA
attribute1 = values1
attribute2 = values2
...
attributen = valuesn
NameOfItemB
attribute1 = values1
attribute2 = values2
...
attributen = valuesn
其中NameOfItemX和attributeX是一组明确定义的已知名称。需要把它变成合理的对象:
ObjectForA.attribute1 = values1
等
我知道我以前做过这件事,只是不记得我是怎么做到的。它看起来像是:
for line in textinput:
if line.find("NameOfItem"):
... parse until next one ...
希望我说的是有道理的,有人可以提供帮助
答案 0 :(得分:2)
这与mgilson的答案类似,不过它将数据放在嵌套字典中。
from collections import defaultdict
itemname = None
d = defaultdict(dict)
for line in data:
line = line.rstrip()
if '=' in line:
attr, value = line.split('=',1)
d[itemname][attr] = value
else:
itemname = line
答案 1 :(得分:1)
将它作为嵌套字典怎么样:
x = {'NameOfItemA': {'attribute1': 'value1', 'attribute2': 'value2'},...}
然后您可以将值引用为:
value2 = x['NameOfItemA']['attribute2']
并且,假设该属性,值始终遵循标题,例如NameOfItemN
:
items = {}
for line in textinput:
if line.find("NameOfItem"):
headline = line
inner_dict = {}
items[headline] = inner_dict
else:
attr, val = line.split('=',1)
items[headline][attr] = val
答案 2 :(得分:1)
这是一个你可能感兴趣的pyparsing解决方案。我已经添加了很多评论来完成代码。
data = """\
NameOfItemA
attribute1 = values1A
attribute2 = values2A
attributen = valuesnA
NameOfItemB
attribute1 = values1B
attribute2 = values2B
attributen = valuesnB
"""
from pyparsing import Suppress, Word, alphas, alphanums, \
empty, restOfLine, Dict, OneOrMore, Group
# define some basic elements - suppress the '=' sign because, while
# it is important during the parsing process, it is not an interesting part
# of the results
EQ = Suppress('=')
ident = Word(alphas, alphanums)
# an attribute definition is an identifier, and equals, and whatever is left
# on the line; the empty advances over whitespace so lstrip()'ing the
# values is not necessary
attrDef = ident + EQ + empty + restOfLine
# define a section as a lone ident, followed by one or more attribute
# definitions (using Dict will allow us to access attributes by name after
# parsing)
section = ident + Dict(OneOrMore(Group(attrDef)))
# overall grammar is defined as a series of sections - again using Dict to
# give us attribute-name access to each section's attributes
sections = Dict(OneOrMore(Group(section)))
# parse the string, which gives back a pyparsing ParseResults
s = sections.parseString(data)
# get data using dotted attribute notation
print s.NameOfItemA.attribute2
# or access data like it was a nested dict
print s.keys()
for k in s.keys():
print s[k].items()
打印:
values2A
['NameOfItemB', 'NameOfItemA']
[('attribute2', 'values2B'), ('attribute1', 'values1B'), ('attributen', 'valuesnB')]
[('attribute2', 'values2A'), ('attribute1', 'values1A'), ('attributen', 'valuesnA')]
答案 3 :(得分:0)
怎么样:
class obj(object): pass
items={}
for line in textinput:
if(line.find("NameOfItem")!=-1):
current_object=items[line.replace("NameOfItem","")]=obj()
else:
attr,val=line.split('=',1)
setattr(current_object,attr.strip(),val.strip())
当然,如果你已经有一个想要使用的类,你可以省略基本对象... 毕竟说完了,你有一个对象字典,其中有keys = object_names和values = attributes(作为字符串 - 你需要转换成它应该是什么类型,如果它不是一个字符串)
另请注意,此输入文件格式与ConfigParser
模块的 A LOT 类似。您可以读取该文件并将"NameOfItem"
行更改为[item]
行,并将其作为StringIO对象传递给ConfigParser ...