Pyparsing:setResultsName的问题

时间:2014-03-29 15:02:10

标签: python pyparsing

我正在使用多个答案解析多项选择题,如下所示:

ParserElement.setDefaultWhitespaceChars(u""" \t""")
in_ = """1) first stem.
= option one one key
= option one two key
- option one three distractor
= option one four key
2) second stem ?
- option two one distractor
- option two two distractor
= option one three key
3) third stem.
- option three one key
= option three two distractor
"""

等号代表正确的答案,破折号代表分心者。

我的语法看起来像这样:

newline = Suppress(u"\n")
end_number = Suppress(oneOf(u') / ('))
end_stem = Suppress(oneOf(u"? .")) + newline
end_phrase = Optional(u'.').suppress() + newline
phrase = OneOrMore(Word(alphas)) + end_phrase
prefix = Word(u"-", max=1)('distractor') ^ Word(u"=", max=1)('key')
stem = Group(OneOrMore(Word(alphas))) + end_stem
number = Word(nums) + end_number
question = number + stem('stem') +
    Group(OneOrMore(Group(prefix('prefix') + phrase('phrase'))))('options')

当我解析结果时:

for match, start, end in question.scanString(in_):
    for o in match.options:
        try:
            print('key', o.prefix.key)
        except:
            print('distractor', o.prefix.distractor)

我明白了:

AttributeError: 'unicode' object has no attribute 'distractor'

我非常确定结果名称是可链接的。如果是这样,我做错了什么?我可以很容易地解决这个问题,但不知道我做错了什么以及我误解了什么都不能令人满意。

1 个答案:

答案 0 :(得分:3)

问题是o实际上是前缀 - 当你调用o.prefix时,实际上你需要更深一级,并且正在检索前缀映射到的字符串,不是ParseResults对象。

您可以通过修改代码以便打印出解析树来看到这一点:

for match, start, end in question.scanString(in_):
    for o in match.options:
        print o.asXML()
        try:
            print('key', o.prefix.key)
        except:
            print('distractor', o.prefix.distractor)

然后打印出代码:

<prefix>
  <key>=</key>
  <phrase>option</phrase>
  <ITEM>one</ITEM>
  <ITEM>one</ITEM>
  <ITEM>key</ITEM>
</prefix>
Traceback (most recent call last):
  File "so07.py", line 37, in <module>
    print('distractor', o.prefix.distractor)
AttributeError: 'str' object has no attribute 'distractor'

然后问题变得清晰 - 如果o是前缀,则执行o.prefix没有意义。相反,您只需致电o.keyo.distractor

此外,如果您尝试调用不存在密钥的o.key,则pyparsing将返回空字符串而不是抛出异常。

因此,您的固定代码应如下所示:

for match, start, end in question.scanString(in_):
    for o in match.options:
        if o.key != '':
            print('key', o.key)
        else:
            print('distractor', o.distractor)