好的,我想出了一个最终的解决方案,该解决方案实际上将数据转换为我最初想要的JSON友好型Dict。它首先使用Pyparsing将数据转换为一系列嵌套列表,然后循环遍历该列表并将其转换为JSON。这使我能够克服以下问题:Pyparsing的
toDict()方法无法处理同一对象具有相同名称的两个属性的情况。为了确定列表是纯列表还是属性/值对,当Pyparsing检测到属性名称时,该
prependPropertyToken方法会将字符串添加到
__property__属性名称的前面。
def parse_file(self,fileName): #get the input text file file = open(fileName, "r") inputText = file.read() #define data types that might be in the values real = Regex(r"[+-]?d+.d*").setParseAction(lambda x: float(x[0])) integer = Regex(r"[+-]?d+").setParseAction(lambda x: int(x[0])) yes = CaselessKeyword("yes").setParseAction(replaceWith(True)) no = CaselessKeyword("no").setParseAction(replaceWith(False)) quotedString.setParseAction(removeQuotes) unquotedString = Word(alphanums+"_-?"") comment = Suppress("#") + Suppress(restOfLine) EQ,LBRACE,RBRACE = map(Suppress, "={}") data = (real | integer | yes | no | quotedString | unquotedString) #define structures value = Forward() object = Forward() dataList = Group(oneOrMore(data)) simpleArray = (LBRACE + dataList + RBRACE) propertyName = Word(alphanums+"_-.").setParseAction(self.prependPropertyToken) property = dictOf(propertyName + EQ, value) properties = Dict(property) object << (LBRACE + properties + RBRACE) value << (data | object | simpleArray) dataset = properties.ignore(comment) #parse it result = dataset.parseString(inputText) #turn it into a JSON-like object dict = self.convert_to_dict(result.asList()) return json.dumps(dict) def convert_to_dict(self, inputList): dict = {} for item in inputList: #determine the key and value to be inserted into the dict dictval = None key = None if isinstance(item, list): try: key = item[0].replace("__property__","") if isinstance(item[1], list):try: if item[1][0].startswith("__property__"): dictval = self.convert_to_dict(item) else: dictval = item[1]except AttributeError: dictval = item[1] else:dictval = item[1] except IndexError: dictval = None #determine whether to insert the value into the key or to merge the value with existing values at this key if key: if key in dict: if isinstance(dict[key], list):dict[key].append(dictval) else:old = dict[key]new = [old]new.append(dictval)dict[key] = new else: dict[key] = dictval return dict def prependPropertyToken(self,t): return "__property__" + t[0]


