簡體   English   中英

在使用pyparsing並將結果作為字典返回時如何保留類型

[英]how to preserve types when using pyparsing and returning the result as a dictionary

我是pyparsing的新手,希望有人能幫助我。我要解析的文本類型具有以下結構:

我在一行中可以有一個或多個對的key = value對。 值可以有許多類型,例如字符串,整數,浮點數,列表,字典。 密鑰始終是字符串。 4對線的示例:

mode ='clip'clipzeros = True字段='1331 + 0444 = 3C286'clipminmax = [0,1.2]

因此,我將語法和解析器定義為:

import pyparsing as pp

key = pp.Word(pp.alphas+"_")
separator = pp. Literal("=").suppress()
value = pp.Word(pp.printables)
pair = key+separator+value

line = pp.OneOrMore(pair)

mytest = "mode='clip' clipzeros=True field='1331+0444=3C286' clipminmax=[0,1.2]"
res = line.parseString(mytest)
print res

它返回以下內容:

['mode','clip','clipzeros','True','field',''1331 + 0444 = 3C286','clipminmax','[0,1.2]']

我希望得到兩件事:

  1. 我想將結果作為字典,例如:{“ mode”:“ clip”,“ clipzeros”:True,“ field”:“ 1331 + 0444 = 3C286”,“ clipminmax”:[0,1.2] }

  2. 我想在結果字典中保留值的類型。 例如:值clipzeros的類型是一個布爾值。 clipminmax值的類型是一個列表。

pyparsing這完全可能嗎?

非常感謝您的幫助。

桑德拉

嘗試使用eval()獲取類型。

import pyparsing as pp

key = pp.Word(pp.alphas+"_")
separator = pp. Literal("=").suppress()
value = pp.Word(pp.printables)
pair = key+separator+value

line = pp.OneOrMore(pair)

mytest = "mode='clip' clipzeros=True field='1331+0444=3C286' clipminmax=[0,1.2]"
res = line.parseString(mytest)
mydict = dict(zip(res[::2],[eval(x) for x in res[1::2]])

產量:

{'field': '1331+0444=3C286', 'mode': 'clip', 'clipzeros': True, 'clipminmax': [0, 1.2]}

另一個例子:

res = ['mode', "'clip'", 'clipzeros', 'True', 'field', "'R RQT'", 'clipminmax', '[0,1.2]']
mydict = dict(zip(res[::2],[eval(x) for x in res[1::2]]))

print mydict

產量:

  {'field': 'R RQT', 'mode': 'clip', 'clipzeros': True, 'clipminmax': [0, 1.2]}

替代pyparser(我沒有那個模塊):

class Parser():
    def __init__(self,primarydivider,secondarydivider):
        self.prime = primarydivider
        self.second = secondarydivider

    def parse(self,string):
        res = self.initialsplit(string)
        new = []
        for entry in res:
            if self.second not in entry:
                new[-1] += ' ' + entry
            else:
                new.append(entry)
        return dict((entry[0],eval(entry[1])) for entry in [entry.split(self.second) for entry in new])

    def initialsplit(self,string):
        return string.split(self.prime)

mytest = "mode='clip' clipzeros=True field='AEF D' clipminmax=[0,1.2]"
myParser = Parser(' ', '=')
parsed = myParser.parse(mytest)
print parsed

產量

 {'field': 'AEF D', 'mode': 'clip', 'clipzeros': True, 'clipminmax': [0, 1.2]}

OP的評論編輯:

Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> mytest = "mode='clip' clipzeros=True field='R RQT' clipminmax=[0,1.2]"
>>> print mytest
mode='clip' clipzeros=True field='R RQT' clipminmax=[0,1.2]
>>>

我建議不要使用與Word(printables)一樣通用的東西,而建議為不同類型的值文字定義特定的表達式:

from pyparsing import *

# what are the different kinds of values you can get?
int_literal = Combine(Optional('-') + Word(nums))
float_literal = Regex(r'\d+\.\d*')
string_literal = quotedString
bool_literal = Keyword("True") | Keyword("False")
none_literal = Keyword("None")
list_literal = originalTextFor(nestedExpr('[',']'))
dict_literal = originalTextFor(nestedExpr('{','}'))

# define an overall value expression, of the different types of values
value = (float_literal | int_literal | bool_literal | none_literal | 
        string_literal | list_literal | dict_literal)

key = Word(alphas + '_')

def evalValue(tokens):
    import ast
    # ast.literal_eval is safer than global eval()
    return [ast.literal_eval(tokens[0])]
pair = Group(key("key") + '=' + value.setParseAction(evalValue)("value"))

line = OneOrMore(pair)

現在解析您的樣本:

sample = """mode='clip' clipzeros=True field='1331+0444=3C286' clipminmax=[0,1.2]"""

result = line.parseString(sample)
for r in result:
    print r.dump()
    print r.key
    print r.value
    print

印刷品:

['mode', '=', 'clip']
- key: mode
- value: clip
mode
clip

['clipzeros', '=', True]
- key: clipzeros
- value: True
clipzeros
True

['field', '=', '1331+0444=3C286']
- key: field
- value: 1331+0444=3C286
field
1331+0444=3C286

['clipminmax', '=', [0, 1.2]]
- key: clipminmax
- value: [0, 1.2]
clipminmax
[0, 1.2]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM