通过我的方式:
Pyparsing Quick Reference, Chapter 3: Small Example -
示例解析器应该匹配有效的Python标识符,所以
'a_#'
应该无效,就像作者评论一样,对吧?但是,在页面底部:
---Test for 'a_#'
Matches: ['a', '_']
这是解析器:
first = pp.Word(pp.alphas+"_", exact=1)
rest = pp.Word(pp.alphanums+"_")
identifier = first+pp.Optional(rest)
我不确定,所以在联系作者之前我想要一些反馈意见。
另外,我试图通过构造一个只接受整个字符串中定义的字符范围的解析器来纠正它,因此它不会匹配它的前缀。不能正确 - 任何建议?
答案 0 :(得分:1)
糟糕!使用两个Word
来构建标识符是浪费,低效,并且只是糟糕的pyparsing实践。我认为作者这样做是为了展示如何在这里使用Combine
,但是后来,他应该只使用一个Word
表达式来展示更好的选择。
Word
有两个参数格式(清楚地描述in the online docs):
valid_ident_leading_chars = alphas + '_'
valid_ident_body_chars = alphanums + '_'
identifier = Word(valid_ident_leading_chars, valid_ident_body_chars)
(顺便说一下,这相当于:
identifier = Regex('['+valid_ident_leading_chars+']['+valid_ident_body_chars+']*')
如果您查看pyparsing代码,您将看到Word
通过构建非常正则的表达式来实现其匹配。)
这仍将解析' a _#'的前导部分,与正则表达式相同。如果您希望测试失败,因为未解析完整字符串,请使用:
identifier.parseString('a_#', parseAll=True)
为了简化编写测试,您还可以使用' ==' - 将pyparsing表达式与字符串进行比较时,表达式将运行expr.parseString(comparison_string, parseAll=True)
,并根据是否引发ParseException返回True / False。
assert 'a_' == identifier # <-- will pass
assert 'a_#' == identifier # <-- will fail