以下是我目前的情况:
_filter_date_range = pp.Group(_keyword_date + pp.Group(
pp.Group(_function_before + _argument_string) & pp.Group(_function_after + _argument_string)
))
由于我使用Each
(&
),因此两个表达式都是必需的。但我想允许:
如果我同时制作两个组Optional
,我也不会允许,我不想要。那么我可以使用它吗?
答案 0 :(得分:3)
@ 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
接受一个必须返回布尔值的可调用(具有与addParseAction
相同的调用签名支持)。如果返回False,则该条件将导致引发ParseException。 (这是使用解析操作作为验证器的用例的简化。)在这种情况下,我们需要的只是Python内置bool
,因为ParseResults与所有Python本机序列一样,在空时评估为False否则就是真的。
答案 1 :(得分:2)
以下是三种可能的解决方案:
from pyparsing import Literal, OneOrMore, Optional
A = Literal("A")
B = Literal("B")
language = OneOrMore( A | B )
assert language.matches("A")
assert language.matches("B")
assert language.matches("A B")
assert language.matches("B A")
assert language.matches("A A")
assert language.matches("B B")
assert language.matches("A B A B")
assert not language.matches("")
def EitherOrBoth(a, b):
return (a + b) | (b + a) | a | b
language = EitherOrBoth(A, B)
assert language.matches("A")
assert language.matches("B")
assert language.matches("A B")
assert language.matches("B 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("")
def EitherOrBoth(a, b):
return (a + Optional(b)) | (b + Optional(a))
language = EitherOrBoth(A, B)
assert language.matches("A")
assert language.matches("B")
assert language.matches("A B")
assert language.matches("B 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("")