pyparsing provides a helper function, delimitedList, that matches a sequence of one or more expressions, separated with a delimiter:
delimitedList(expr, delim=',', combine=False)
How can this be used to match a sequence of expressions, where each expression may occur zero or one times?
For example, to match "foo", "bar, "baz" I took a bottom-up approach a created a token for each word:
import pyparsing as pp
dbl_quote = pp.Suppress('"')
foo = dbl_quote + pp.Literal('foo') + dbl_quote
bar = dbl_quote + pp.Literal('bar') + dbl_quote
baz = dbl_quote + pp.Literal('baz') + dbl_quote
I want to create an expression that matches:
zero or one occurrences of
"foo", zero or one occurrences of"bar", zero or one occurrences of"baz"
... in any order. Examples of valid input:
"foo", "bar", "baz""baz", "bar", "foo",// Order is unimportant"bar", "baz"// Zero occurrences allowed"baz"// Zero occurrences of all tokens
Examples of invalid input:
"notfoo", "notbar", "notbaz""foo", "foo", "bar", "baz"// Two occurrences offoo"foo" "bar", "baz"// Missing comma"foo" "bar", "baz",// Trailing comma
I gravitated towards delimitedList because my input is a comma delimited list, but now I feel this function is working against me rather than for me.
import pyparsing as pp
dbl_quote = pp.Suppress('"')
foo = dbl_quote + pp.Literal('foo') + dbl_quote
bar = dbl_quote + pp.Literal('bar') + dbl_quote
baz = dbl_quote + pp.Literal('baz') + dbl_quote
# This is NOT what I want because it allows tokens
# to occur more than once.
foobarbaz = pp.delimitedList(foo | bar | baz)
if __name__ == "__main__":
TEST = '"foo", "bar", "baz"'
results = foobarbaz.parseString(TEST)
results.pprint()