我以为我理解pyparsing的逻辑,但无法弄清楚为什么下面的示例失败了。
我正在尝试分析开放文本注释,在注释的开头或结尾可以提及一个产品或一组产品。产品名称也可以从注释中省略。
输出应为上述产品及其相关描述的列表。
下面是一些测试用例。解析将所有内容都标识为“描述”,而不是先提取产品(这不是底片应该做什么吗?)
我的理解有什么问题?
import pyparsing as pp
products_list = ['aaa', 'bbb', 'ccc']
products = pp.OneOrMore(' '.join(products_list))
word = ~products + pp.Word(pp.alphas)
description = pp.OneOrMore(word)
comment_expr = (pp.Optional(products("product1")) + description("description") + pp.Optional(products("product2")))
matches = comment_expr.scanString("""\
aaa is a good product
I prefer aaa
No comment
aaa bbb are both good products""")
for match in matches:
print match
预期结果将是:
product1: aaa, description: is a good product
product2: aaa, description: I prefer
description: No comment
product1: [aaa, bbb] description: are both good products
答案 0 :(得分:1)
Pyparsing在字符串和文字之间的快捷方式等效项是为了方便起见,但有时会导致意外和意外的情况。在这些行中:
products_list = ['aaa', 'bbb', 'ccc']
products = pp.OneOrMore(' '.join(products_list))
。 我很确定您希望产品能够与任何产品匹配。但是相反,OneOrMore将此作为其参数传递:
' '.join(products_list)
这纯粹是一个字符串表达式,产生 string “ aaa bbb ccc”。将其传递给OneOrMore,就是说产品是字符串“ aaa bbb ccc”的一个或多个实例。
要获得前瞻性,您需要将产品更改为:
products = pp.oneOf(products_list)
甚至更好:
products = pp.MatchFirst(pp.Keyword(p) for p in products_list)
那么,您的否定前瞻会更好。