【问题标题】:How to parse this special config file in python?如何在 python 中解析这个特殊的配置文件?
【发布时间】:2012-12-05 07:16:09
【问题描述】:

我有一些配置文件,数据格式无法更改。

其中一个看起来像这样:

root {
  configuration {
    field_a: "aaaa"
    field_b: "bbbb"
  }
  child {
    configuration {
        field_a: "aaa1"
        field_b: "bbb1"
    }
  }
  child {
    configuration {
        field_a: "aaa2"
        field_b: "bbb2"
    }
  }
}

我需要的是解析文件并将其保存为 JSON 对象:

{root: 
    {field_a:"aaaa",field_b:"bbbb"},
    children: [{field_a:"aaa", field_b:"bbb"}, ... ]
}

有什么办法可以实现吗?

【问题讨论】:

  • 您肯定需要编写一个简单的词法分析器和一个解析器。这个文件的格式是什么?你是 python 模块还没有完成这项工作吗?
  • 看pyparsing。
  • @nathan 文件格式是我们很久以前定义的,我没有看到任何模块可以做到这一点。
  • @BrenBarn 谢谢,看起来很棒,我会尝试使用它。
  • 这种格式是否已经并且可靠地排列整齐并缩进了?

标签: python json parsing configuration-files data-transfer-objects


【解决方案1】:

快速思考:

如果配置良好的缩进和内衬为例:

替换 "{" 和 "}" 使其如下:

root:
  configuration:
    field_a: "aaaa"
    field_b: "bbbb"
  child:
    configuration:
        field_a: "aaa"
        field_b: "bbb"

现在它是一个 yaml 格式的文件! 一定要从 yaml 转换为 json !

import yaml
import json

s = "yamlstr"  # your yaml str
data = yaml.load(s)
jsondata = json.dumps(data)
print jsondata

更新

由于 child 是一个列表,并且“root”、“configuration”和“child”似乎都是关键字,所以稍微改变一下并寻找解决方法:

做到这一点:

root:
  - configuration:
    field_a: "aaaa"
    field_b: "bbbb"
  - child:
    - configuration:
        field_a: "aaa1"
        field_b: "bbb1"
  - child:
    - configuration:
        field_a: "aaa2"
        field_b: "bbb2"

输出 python dict 将是:

{'root': [{'configuration': None, 'field_b': 'bbbb', 'field_a': 'aaaa'}, {'child': [{'configuration': {'field_b': 'bbb1', 'field_a': 'aaa1'}}]}, {'child': [{'configuration': {'field_b': 'bbb2', 'field_a': 'aaa2'}}]}]}

现在做一些简单的编程,让它成为你的结构:-)

【讨论】:

  • 谢谢,看看我的更新,我可能有很多相同缩进级别的孩子。
  • @MrROY 答案已更新,而且您仍然不需要复杂的字符串解析器 :-)
【解决方案2】:

您的数据格式是 unofficial-javascript-array。对于伟大的 python,很容易用 4 行代码将它们解析为 python dict。然后使用 simplejson 解析为您喜欢的任何 json 格式。

s = '''                                                                                                          
root {                                                                                                           
  configuration {                                                                                                
    field_a: "aaaa"                                                                                              
    field_b: "bbbb"                                                                                              
  }                                                                                                              
  child {                                                                                                        
    configuration {                                                                                              
        field_a: "aaa"                                                                                           
        field_b: "bbb"                                                                                           
    }                                                                                                            
  }                                                                                                              
}                                                                                                                
'''                                                                                                              

s = s.replace("{", ":{").replace("}", "},")                                                                      
s = "{%s}"%s                                                                                                     

import re                                                                                                        
s = re.sub(r'(\w+)"', r'\1",', s)                                                                                
s = re.sub(r"(\w+)\s*\:", r'"\1":', s)                                                                           
print "string:", s                                                                                               

d = eval(s)                                                                                                      
print "python dict:", d                                                                                          

import simplejson as json                                                                                        
print "json:", json.dumps(d) 

【讨论】:

  • 我可能有很多相同缩进级别的孩子,所以在你的例子中,最后一个孩子将覆盖以前的孩子。
  • 唯一键是 JSON 规则之一。 Javascript数组支持写入重复键,但只能读出最后一个键。
猜你喜欢
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多