在 pyparsing 中正确使用 nestedExpr
proper use of nestedExpr in pyparsing
我有一个键值对的嵌套表示,例如:
案例 1:
str = " value 23"
案例二:
str = " value { \
{'name' {value 'joint'}},
{'id' {value 51}} \
}"
或者情况3:
str = " value { \
{ 'drive' { value 'joint1'}}, \
{ 'steer' { value 45.35}}
}"
可以看出,嵌套层数是无限的。例如在上面的例子中,'joint2'
也可以有大括号。 value
是这里唯一的关键字。最后,值可以是整数、浮点数或单引号字符串。
我这里有一个非常简单的代码:
field_name = Keyword("value").supress()
real = Combine(Word(nums) + '.' + Word(nums))
values = real | Word(
nums) | sglQuotedString.setParseAction(removeQuotes)
nested = nestedExpr('{', '}')
grammar = field_name + \
(values | (nestedExpr('{', '}') + Optional(',').suppress()))("values")
对于情况 2,我得到一个输出
{'values': [[["'name'", ['value', "'joint'"]], ',', ["'id'", ['value', '51']]]]}
首先 ','
和 value
也被解析。其次,我不确定我是否正确使用 nestedExpr
。我应该在 nestedExpr
中使用 Dict
吗?
编辑 1:
我已经发布了上述案例的解决方案,但我意识到案例 2 和案例 3 是相同的。我真正想展示的是
案例 4:
str = "value { \
{'name' {value 'joint1' { \
value 12} \
} \
} \
}, \
{'id' {value 51}} \
}"
对于这种情况,我需要知道嵌套有多深吗?
我得到了一个解决方案:
from pyparsing import *
_value = Keyword("value").suppress()
real = Combine(Word(nums) + '.' + Word(nums))
values = real | Word(
nums) | sglQuotedString.setParseAction(removeQuotes)
LCB, RCB = map(Suppress, "{}")
param_val = _value + values
param_vals = Dict(OneOrMore(Group(sglQuotedString.setParseAction(
removeQuotes) + nestedExpr('{', '}', content=param_val))))
param_values = _value + \
nestedExpr('{', '}', content=delimitedList(
LCB + param_vals + RCB, delim=','))
str = "value {{'name' {value 'arm_right_1_joint'}}, {'id' {value 51}}}"
res = param_values.parseString(str)
print(res.dump())
我得到结果:
[[['name', ['arm_right_1_joint']], ['id', ['51']]]]
[0]:
[['name', ['arm_right_1_joint']], ['id', ['51']]]
- id: ['51']
- name: ['arm_right_1_joint']
请随时提出其他解决方案。
编辑:
我找到了一个更好的解决方案。现在它可以解析任何级别的递归。
real = Combine(Word(nums) + '.' + Word(nums))
listStr = Forward()
mapStr = Forward()
param_value = Forward()
string_value = Dict(Group(sglQuotedString.setParseAction(
removeQuotes) + ZeroOrMore(LCB + param_value + RCB)))
string_value.setParseAction(parseActionStr)
values = Combine(Optional("-") + real) | Combine(Optional("-") + Word(
nums)) | string_value | Keyword("false") | Keyword("true") | listStr | mapStr
listStr << delimitedList(Group(LCB + delimitedList(values) + RCB))
mapStr << (LSB + delimitedList(Group(LCB + delimitedList((Group(sglQuotedString.setParseAction(removeQuotes) +
Suppress(":") + values))) + RCB)) + RSB)
mapStr.setParseAction(parseActionDict)
param_value << _value + (values | listStr)
结果为:
str_param4 = "value { \
{'type' {value 'laser'}}, \
{'params' {value { \
{'upper_replacement_value' {value 10.0}}, \
{'use_message_range_limits' {value false}}, \
{'upper_threshold' {value 10.0}}}, \
{'name' {value 'range'}}}}}"
是:
[['laser']]
[['range']]
[[[['type', 'laser']], [['params', [[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]]]]
[0]:
[[['type', 'laser']], [['params', [[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]]]
[0]:
[['type', 'laser']]
- type: 'laser'
[1]:
[['params', [[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]]
- params: [[[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]
[0]:
[[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]]
[0]:
[['upper_replacement_value', '10.0']]
- upper_replacement_value: '10.0'
[1]:
[['use_message_range_limits', 'false']]
- use_message_range_limits: 'false'
[2]:
[['upper_threshold', '10.0']]
- upper_threshold: '10.0'
[1]:
[['name', 'range']]
- name: 'range'
我有一个键值对的嵌套表示,例如:
案例 1:
str = " value 23"
案例二:
str = " value { \
{'name' {value 'joint'}},
{'id' {value 51}} \
}"
或者情况3:
str = " value { \
{ 'drive' { value 'joint1'}}, \
{ 'steer' { value 45.35}}
}"
可以看出,嵌套层数是无限的。例如在上面的例子中,'joint2'
也可以有大括号。 value
是这里唯一的关键字。最后,值可以是整数、浮点数或单引号字符串。
我这里有一个非常简单的代码:
field_name = Keyword("value").supress()
real = Combine(Word(nums) + '.' + Word(nums))
values = real | Word(
nums) | sglQuotedString.setParseAction(removeQuotes)
nested = nestedExpr('{', '}')
grammar = field_name + \
(values | (nestedExpr('{', '}') + Optional(',').suppress()))("values")
对于情况 2,我得到一个输出
{'values': [[["'name'", ['value', "'joint'"]], ',', ["'id'", ['value', '51']]]]}
首先 ','
和 value
也被解析。其次,我不确定我是否正确使用 nestedExpr
。我应该在 nestedExpr
中使用 Dict
吗?
编辑 1: 我已经发布了上述案例的解决方案,但我意识到案例 2 和案例 3 是相同的。我真正想展示的是
案例 4:
str = "value { \
{'name' {value 'joint1' { \
value 12} \
} \
} \
}, \
{'id' {value 51}} \
}"
对于这种情况,我需要知道嵌套有多深吗?
我得到了一个解决方案:
from pyparsing import *
_value = Keyword("value").suppress()
real = Combine(Word(nums) + '.' + Word(nums))
values = real | Word(
nums) | sglQuotedString.setParseAction(removeQuotes)
LCB, RCB = map(Suppress, "{}")
param_val = _value + values
param_vals = Dict(OneOrMore(Group(sglQuotedString.setParseAction(
removeQuotes) + nestedExpr('{', '}', content=param_val))))
param_values = _value + \
nestedExpr('{', '}', content=delimitedList(
LCB + param_vals + RCB, delim=','))
str = "value {{'name' {value 'arm_right_1_joint'}}, {'id' {value 51}}}"
res = param_values.parseString(str)
print(res.dump())
我得到结果:
[[['name', ['arm_right_1_joint']], ['id', ['51']]]]
[0]:
[['name', ['arm_right_1_joint']], ['id', ['51']]]
- id: ['51']
- name: ['arm_right_1_joint']
请随时提出其他解决方案。
编辑: 我找到了一个更好的解决方案。现在它可以解析任何级别的递归。
real = Combine(Word(nums) + '.' + Word(nums))
listStr = Forward()
mapStr = Forward()
param_value = Forward()
string_value = Dict(Group(sglQuotedString.setParseAction(
removeQuotes) + ZeroOrMore(LCB + param_value + RCB)))
string_value.setParseAction(parseActionStr)
values = Combine(Optional("-") + real) | Combine(Optional("-") + Word(
nums)) | string_value | Keyword("false") | Keyword("true") | listStr | mapStr
listStr << delimitedList(Group(LCB + delimitedList(values) + RCB))
mapStr << (LSB + delimitedList(Group(LCB + delimitedList((Group(sglQuotedString.setParseAction(removeQuotes) +
Suppress(":") + values))) + RCB)) + RSB)
mapStr.setParseAction(parseActionDict)
param_value << _value + (values | listStr)
结果为:
str_param4 = "value { \
{'type' {value 'laser'}}, \
{'params' {value { \
{'upper_replacement_value' {value 10.0}}, \
{'use_message_range_limits' {value false}}, \
{'upper_threshold' {value 10.0}}}, \
{'name' {value 'range'}}}}}"
是:
[['laser']]
[['range']]
[[[['type', 'laser']], [['params', [[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]]]]
[0]:
[[['type', 'laser']], [['params', [[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]]]
[0]:
[['type', 'laser']]
- type: 'laser'
[1]:
[['params', [[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]]
- params: [[[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]], [['name', 'range']]]
[0]:
[[['upper_replacement_value', '10.0']], [['use_message_range_limits', 'false']], [['upper_threshold', '10.0']]]
[0]:
[['upper_replacement_value', '10.0']]
- upper_replacement_value: '10.0'
[1]:
[['use_message_range_limits', 'false']]
- use_message_range_limits: 'false'
[2]:
[['upper_threshold', '10.0']]
- upper_threshold: '10.0'
[1]:
[['name', 'range']]
- name: 'range'