这是我目前拥有的:
_filter_date_range = pp.Group(_keyword_date + pp.Group(
pp.Group(_function_before + _argument_string) & pp.Group(_function_after + _argument_string)
))
因为我使用了 Each(&),所以两个表达式都是必需的。但我想允许:
- A 或 B
- 或两者兼而有之
- 但至少有一个
- 以任何顺序
如果我将两个组都设置为可选,我也不会允许任何一个,这是我不希望的。那么有什么我可以用的吗?
请您参考如下方法:
@Rob 的第三个选项 EitherOrBoth 在这种情况下效果很好,我认为,但是当你必须处理 3 个或更多时,pyparsing 的 Each 真正发挥作用可以以任何顺序出现的表达式:
from pyparsing import Literal, Each
A = Literal("A")
B = Literal("B")
C = Literal("C")
def noMoreThanOneOfEachAndAtLeastOne(exprs):
ret = Each(map(Optional, exprs))
ret.addCondition(bool)
return ret
language = noMoreThanOneOfEachAndAtLeastOne([A,B,C])
assert language.matches("A")
assert language.matches("B")
assert language.matches("A C B")
assert language.matches("C A")
assert not language.matches("A A")
assert not language.matches("B B")
assert not language.matches("A B A B")
assert not language.matches("")
addCondition 是 pyparsing 的一个相当新的补充,它是 addParseAction 的一个变体。 addCondition 接受一个必须返回 bool 值的可调用对象(具有与 addParseAction 相同的调用签名支持)。如果它返回 False,则该条件将导致引发 ParseException。 (这是对使用解析操作作为验证器的用例的简化。)在这种情况下,我们所需要的只是 Python 内置的 bool,因为 ParseResults 与所有 Python native 序列一样,评估为为空时为假,否则为真。
