我有一个看起来像这样的消息定义文件
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'
依旧......
另外,我可以更改定义文件的格式,如果有人建议修改定义文件格式以便于解析,请告诉我。
由于
答案 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是一个易于使用的好库。那就是我会用的。
答案 5 :(得分:0)
由于您可以自由更改文件格式,因此可以将其更改为具有Python库读取和写入的多种格式中的任何一种。例如,JSON,YAML,XML,甚至是内置的ConfigParser。
[struct1]
field: name
type: string
ignore: false
# etc.