0

我知道我已经看到了一个很好的算法,但是找不到它。

我需要解析的工具(我无法控制其输出样式)的输出(格式不正确)。

它看起来像这样:

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 ...

希望我所说的有道理,有人可以提供帮助

4

4 回答 4

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
于 2012-04-23T19:47:10.290 回答
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
于 2012-04-23T19:53:09.907 回答
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')]
于 2012-04-23T20:16:30.477 回答
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())

当然,如果您已经有一个要使用的类,则可以省略基本对象...毕竟,您有一个对象字典,其中键=对象名称和值=属性(作为字符串-您如果它不是字符串,则需要转换为它应该是的任何类型)

另请注意,此输入文件格式看起来很像ConfigParser模块的格式。您可能可以读取文件并将行更改"NameOfItem"[item]行并将其作为 StringIO 对象传递给 ConfigParser ...

于 2012-04-23T19:36:37.767 回答