我正在使用多个答案解析多项选择题,如下所示:
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'
我非常确定结果名称是可链接的。如果是这样,我做错了什么?我可以很容易地解决这个问题,但不知道我做错了什么以及我误解了什么都不能令人满意。
答案 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.key
或o.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)