Python 2.5.2 中解析数据文件

58 阅读2分钟

在 Python 2.5.2 中,我有如下所示的消息定义文件。

huake_00066_.jpg

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)

以上就是解析数据文件的几种方法。你可以根据自己的需要选择合适的方法。