在python中解析数据文件(2.5.2)

时间:2009-12-17 15:17:10

标签: python parsing dictionary

我有一个看起来像这样的消息定义文件

struct1 
{
  field="name" type="string" ignore="false"; 
  field="id" type="int" enums=" 0="val1" 1="val2" ";
}

struct2
{
  field = "object" type="struct1";
  ...
}

如何将其解析为具有键'struct1,struct2'的字典,并且值应该是字典列表,每个字典对应于相应的行号,以便我可以执行以下操作

dict['struct1'][0]['type'] // Would return 'string'
dict['struct1'][1]['type'] // Would return 'int'
dict['struct1'][1]['enums']['0'] // Would return 'val1'
dict['struct2'][0]['type'] // Would return 'struct1'

依旧......

另外,我可以更改定义文件的格式,如果有人建议修改定义文件格式以便于解析,请告诉我。

由于

6 个答案:

答案 0 :(得分:4)

使用可以使用json作为文件格式,它支持(在python术语中)字典和列表。由于json支持仅适用于python 2.6及更高版本,因此您需要使用此库:http://pypi.python.org/pypi/simplejson/2.0.9

{ "struct1" 
    [
        {"field" : "name", "type" : "string", "ignore" : false },
        {"field" : "id", "type" : "int", "0" : "val1", "1" : "val2" }
        {"field" : "id", "type" : "int", "enums" : { "0": "val1", "1": "val2"}}
    ]
  "struct2"
    [ ... ]
}

python part(草绘,未测试):

>>> import simplejson as json
>>> d = json.loads(yourjsonstring)
>>> d['struct1'][0]['field']
name
>>> d['struct1'][2]['enums']['0']
val1
...

答案 1 :(得分:4)

请改用YAML。 python有PyYAML库。谷歌AppEngine大量使用它。

这只是一个友好的建议: - )

示例(将标量映射到序列):

american:
  - Boston Red Sox
  - Detroit Tigers
  - New York Yankees
national:
  - New York Mets
  - Chicago Cubs
  - Atlanta Braves

当然还有JSON对Python有很多支持(但往往会伤害我的手指; - )

答案 2 :(得分:4)

我可以推荐YAML吗?恕我直言,语法对于数据输入更具可读性,然后您不必编写和维护解析器。 Eschew XML - 它有助于标记文本,但不适合数据输入,因为文本不是人类可读的,并且所有重复标记都随处可见。

答案 3 :(得分:2)

我只是使用Python作为消息定义文件格式。

让您的消息定义文件成为普通的Python文件:

# file messages.py
messages = dict(
    struct1=[
        dict(field="name", type="string", ignore=False),
        dict(field="id", type="int", enums={0: "val1", 1: "val2"}),
        ],
    struct2=[
        dict(field="object", type="struct1"),
        ]
    )

然后,您的程序可以直接导入并使用该数据结构:

# in your program
from messages import messages
print messages['struct1'][0]["type"]
print messages['struct1'][1]['type']
print messages['struct1'][1]['enums'][0]
print messages['struct2'][0]['type']

使用这种方法,您可以让Python为您进行解析。

你也获得了很多可能性。例如,假设您(出于某些奇怪的原因)具有包含名为“field_N”的1000个字段的消息结构。使用传统的文件格式,您必须添加1000行字段定义(除非您在配置文件解析器中构建一些循环 - 然后您就可以开始创建编程语言了)。为此目的使用Python,您可以执行以下操作:

messages = dict(
    ...
    strange_msg=[dict(field="field_%d" % i) for i in range(1000)],
    ...
    )
顺便说一句,在Python 2.6上,使用命名元组而不是dict是一种选择。或者使用众多可用的“束”类(参见Python cookbook,了解2.5的namedtuple)。

修改

下面是读取命令行中指定的消息定义文件的代码。它使用execfile代替import

# file mainprogram.py

def read_messages_from_file(filename):
    module_dict = {}
    execfile(filename, module_dict)
    return module_dict['messages']

if __name__ == "__main__":
    from pprint import pprint
    import sys

    for arg in sys.argv[1:]:
        messages = read_messages_from_file(arg)
        pprint(messages)

执行:

$ python mainprogram.py messages1 messages2 messages3

将读取并打印每个文件中定义的消息。

答案 4 :(得分:1)

Pyparsing是一个易于使用的好库。那就是我会用的。

http://pyparsing.wikispaces.com/

答案 5 :(得分:0)

由于您可以自由更改文件格式,因此可以将其更改为具有Python库读取和写入的多种格式中的任何一种。例如,JSON,YAML,XML,甚至是内置的ConfigParser

[struct1]
field: name
type: string
ignore: false
# etc.