我正在尝试将有效标识符列表传递给解析器。就是说:我有一个包含标识符的列表,解析器应该使用它们,我将它们作为参数传递给构造函数。
我有一个标识符数组identifiers = Literal('identifier1') | Literal('identifier2') | Literal('identifier whatever')
而不是identifiers = ['identifier1', 'identifier2', 'identifier whatever', ... 'identifier I can not what']
,我需要告诉pyparsing用作标识符。
这是我到目前为止所做的:
def __init__(self, idents):
if isinstance(idents, list) and idents:
for identifier in idents:
// and this is where I got stuck
// I tried:
// identifiers = Literal(identifier) but this keeps only the lastone
我该如何实现?
答案 0 :(得分:1)
将字符串列表转换为备用解析表达式列表的最简单方法是使用oneOf
:
import pyparsing as pp
color_expr = pp.oneOf(["red", "orange", "yellow", "green", "blue", "purple"])
# for convenience could also write as pp.oneOf("red orange yellow green blue purple")
# but since you are working with a list, I am show code using a list
parsed_colors = pp.OneOrMore(color_expr).parseString("blue orange yellow purple green green")
# use pprint() to list out results because I am lazy
parsed_colors.pprint()
sum(color_expr.searchString("blue 1000 purple, red red swan okra kale 5000 yellow")).pprint()
打印:
['blue', 'orange', 'yellow', 'purple', 'green', 'green']
['blue', 'purple', 'red', 'red', 'yellow']
因此oneOf(["A", "B", "C"])
和快捷按钮版本oneOf("A B C")
与Literal("A") | Literal("B") | Literal("C")
相同
oneOf
要注意的一件事是它不强制单词边界
pp.OneOrMore(color_expr).parseString("redgreen reduce").pprint()
将打印:
['red', 'green', 'red']
即使开头的“红色”和“绿色”不是分开的单词,而最后的“红色”只是“减少”的第一部分。这正是使用由Literal
建立的显式表达式所得到的行为。
要强制使用单词边界,必须使用Keyword类,现在必须使用更多的Python来构建单词边界。
您将需要为替代项构建一个Or或MatchFirst表达式。通常,您使用'^'或'|'建立这些运算符。但是要使用表达式列表创建其中之一,则可以调用构造函数形式Or(expression_list)
或MatchFirst(expression_list)
。
如果您有字符串列表,您可以可以创建Or(list_of_identifiers)
,但这默认是将字符串转换为文字,我们已经看到您没有不想那样。
相反,使用字符串使用Python列表推导或生成器表达式创建关键字表达式,然后将其传递给MatchFirst
构造函数(MatchFirst比Or更有效,关键字匹配将是安全的与MatchFirst的短路逻辑配合使用)。以下内容将全部相同,只是在如何构建关键字序列并将其传递给MatchFirst构造函数方面稍有不同:
# list comprehension
MatchFirst([Keyword(ident) for ident in list_of_identifiers])
# generator expression
MatchFirst(Keyword(ident) for ident in list_of_identifiers)
# map built-in
MatchFirst(map(Keyword, list_of_identifiers))
这是颜色匹配的示例,使用关键字重做。请注意,现在 不匹配大单词中嵌入的颜色:
colors = ["red", "orange", "yellow", "green", "blue", "purple"]
color_expr = pp.MatchFirst(pp.Keyword(color) for color in colors)
sum(color_expr.searchString("redgreen reduce skyblue boredom purple 100")).pprint()
打印:
['purple']