给出一个嵌套列表:
(layer 0
(dielectric FR4)
(thickness 0.005)
)
(layer 1
(dielectric copper)
(thickness 0.01)
)
(layer 2
(dielectric FR4)
(thickness 0.005)
)
(physicalLayerGroup "TOP"
(minLineWidth ALWAYS_CHECK)
(maxLineWidth ALWAYS_CHECK)
(maxBondingWireLength NEVER_CHECK)
(minBondingWireLength NEVER_CHECK)
)
(physicalLayerGroup "L02"
(minLineWidth ALWAYS_CHECK)
(maxLineWidth ALWAYS_CHECK)
(maxBondingWireLength NEVER_CHECK)
(minBondingWireLength NEVER_CHECK)
)
(physicalLayerGroup "L03"
(minLineWidth ALWAYS_CHECK)
(maxLineWidth ALWAYS_CHECK)
(maxBondingWireLength NEVER_CHECK)
(minBondingWireLength NEVER_CHECK)
)
即列表,其中每个令牌的第一个元素相同,我该如何对它们进行分组?听起来像addCondition()会适合这个账单,但是如何编码呢?如下所示:
pp.OneOrMore( pp.Word.setName('keyy'), pp.Word.setName('valu'), pp.OneOrMore( pp.ParseResults() ).setParseAction( foo).addCondition( keyy is constant)
有什么想法吗?
code_warrior
答案 0 :(得分:0)
假设您知道每个组的名称,最简单的方法是按预期名称依次匹配每个组。使用辅助函数(我在下面定义为outer_group
)使这更容易:
text = """
(layer 0
(dielectric FR4)
(thickness 0.005)
)
... etc. ...
)"""
import pyparsing as pp
LPAR, RPAR = map(pp.Suppress, "()")
key_expr = pp.Word(pp.alphas)
qs = pp.quotedString().addParseAction(pp.removeQuotes)
val_expr = pp.pyparsing_common.number | qs | pp.Word(pp.printables, excludeChars='()')
# Dict keys need to be converted to str's
subgroup_key = val_expr().addParseAction(lambda t: str(t[0]))
subgroup = pp.Dict(pp.OneOrMore(pp.Group(LPAR + key_expr + val_expr + RPAR)))
# use this method to define each group by name
def outer_group(group_name):
lookahead = pp.FollowedBy(LPAR + pp.Suppress(group_name))
return lookahead + pp.Dict(pp.ZeroOrMore(pp.Group(LPAR
+ pp.Suppress(group_name)
+ subgroup_key
+ subgroup
+ RPAR)))(group_name)
# define groups by name as given in the posted question
# '&' operator generates an Each expression, which allows the groups to be
# parsed in any order
parser = outer_group('layer') & outer_group('physicalLayerGroup')
# how it works
data = parser.parseString(text)
print(data.dump())
print(data.layer['0'].dielectric)
print(data.physicalLayerGroup.TOP.maxLineWidth)
打印:
[[['0', ['dielectric', 'FR4'], ['thickness', 0.005]], ['1', ['dielectric', 'copper'], ['thickness', 0.01]], ['2', ['dielectric', 'FR4'], ['thickness', 0.005]]], [['TOP', ['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']], ['L02', ['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']], ['L03', ['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']]]]
- layer: [['0', ['dielectric', 'FR4'], ['thickness', 0.005]], ['1', ['dielectric', 'copper'], ['thickness', 0.01]], ['2', ['dielectric', 'FR4'], ['thickness', 0.005]]]
- 0: [['dielectric', 'FR4'], ['thickness', 0.005]]
- dielectric: 'FR4'
- thickness: 0.005
- 1: [['dielectric', 'copper'], ['thickness', 0.01]]
- dielectric: 'copper'
- thickness: 0.01
- 2: [['dielectric', 'FR4'], ['thickness', 0.005]]
- dielectric: 'FR4'
- thickness: 0.005
- physicalLayerGroup: [['TOP', ['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']], ['L02', ['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']], ['L03', ['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']]]
- L02: [['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']]
- maxBondingWireLength: 'NEVER_CHECK'
- maxLineWidth: 'ALWAYS_CHECK'
- minBondingWireLength: 'NEVER_CHECK'
- minLineWidth: 'ALWAYS_CHECK'
- L03: [['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']]
- maxBondingWireLength: 'NEVER_CHECK'
- maxLineWidth: 'ALWAYS_CHECK'
- minBondingWireLength: 'NEVER_CHECK'
- minLineWidth: 'ALWAYS_CHECK'
- TOP: [['minLineWidth', 'ALWAYS_CHECK'], ['maxLineWidth', 'ALWAYS_CHECK'], ['maxBondingWireLength', 'NEVER_CHECK'], ['minBondingWireLength', 'NEVER_CHECK']]
- maxBondingWireLength: 'NEVER_CHECK'
- maxLineWidth: 'ALWAYS_CHECK'
- minBondingWireLength: 'NEVER_CHECK'
- minLineWidth: 'ALWAYS_CHECK'
FR4
ALWAYS_CHECK
通过调用asDict()
将解析后的结构转换为JSON# emit JSON from parsed results
import json
print(json.dumps(data.asDict(), indent=' '))
打印:
{
"physicalLayerGroup": {
"TOP": {
"minBondingWireLength": "NEVER_CHECK",
"minLineWidth": "ALWAYS_CHECK",
"maxBondingWireLength": "NEVER_CHECK",
"maxLineWidth": "ALWAYS_CHECK"
},
"L02": {
"minBondingWireLength": "NEVER_CHECK",
"minLineWidth": "ALWAYS_CHECK",
"maxBondingWireLength": "NEVER_CHECK",
"maxLineWidth": "ALWAYS_CHECK"
},
"L03": {
"minBondingWireLength": "NEVER_CHECK",
"minLineWidth": "ALWAYS_CHECK",
"maxBondingWireLength": "NEVER_CHECK",
"maxLineWidth": "ALWAYS_CHECK"
}
},
"layer": {
"0": {
"dielectric": "FR4",
"thickness": 0.005
},
"1": {
"dielectric": "copper",
"thickness": 0.01
},
"2": {
"dielectric": "FR4",
"thickness": 0.005
}
}
}