在 Python 2.5.2 中,我有如下所示的消息定义文件。
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']将返回string。dict['struct1'][1]['type']将返回int。dict['struct1'][1]['enums']['0']将返回val1。dict['struct2'][0]['type']将返回struct1。
我还可能改变定义文件的格式,如果您有建议来修改定义文件的格式以使其更容易解析,请告诉我。
2、解决方案
你可以使用 JSON 作为文件格式,它支持(用 Python 术语来说)字典和列表。由于 JSON 兼容性在 Python 2.6 及更高版本中才成为原生特性,因此你需要这个库: pypi.python.org/pypi/simple…
JSON 格式示例:
{
"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 部分(草图,未经测试):
>>> import simplejson as json
>>> d = json.loads(yourjsonstring)
>>> d['struct1'][0]['field']
name
>>> d['struct1'][2]['enums']['0']
val1
...
你可以使用 YAML。YAML 的语法对于数据输入来说更易读,这样你就不用编写和维护解析器。避免使用 XML —— 它适用于标记文本,但不适合数据输入,因为文本不是人类可读的,到处都是重复的标签。
YAML 示例(将标量映射到序列):
american:
- Boston Red Sox
- Detroit Tigers
- New York Yankees
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves
你也可以直接使用 Python 作为消息定义文件格式。比如,你可以创建一个名为 messages.py 的 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']
你还可以使用 Pyparsing 库来解析数据文件。Pyparsing 是一个易于使用的库。
import pyparsing as pp
# 定义语法
message_name = pp.Word(pp.alphas)
field = pp.Group(pp.Word(pp.alphas) + pp.Literal("=") + pp.Word(pp.alphas))
struct = pp.Group(message_name + pp.Literal("{") + pp.ZeroOrMore(field) + pp.Literal("}"))
# 解析文件
with open("message_definitions.txt", "r") as f:
definitions = f.read()
result = struct.parseString(definitions)
# 从解析结果中构建字典
messages = {}
for struct in result:
messages[struct[0]] = [dict(field.split("=")) for field in struct[1:]]
# 打印字典
print(messages)
以上就是解析数据文件的几种方法。你可以根据自己的需要选择合适的方法。