我正在尝试使用pyparsing解析文本。我的功能如下所示。首先,我构建了一个列表,其中包含我的词典中的所有术语(我网站中常用术语的词典)。然后我将我的语法设置为常用单词列表。然后我用语法构造ZeroOrMore对象。最后,我解析字符串,我应该得到我的字符串中找到的匹配项。但是,它会抛出ParseException而不是抱怨文本的结尾是预期的。
def map_dict_words(self, pbody):
dict_terms = [term.term for term in Dictionary.objects()]
look_for_these = oneOf(dict_terms, caseless=True).setResultsName("dict_words")
parseobj = ZeroOrMore(look_for_these)
matches = parseobj.parseString(pbody, parseAll=True)
print matches
根据pyparsing主页http://pyparsing-public.wikispaces.com/FAQs中的FAQ,如果我希望解析器解析整个字符串,我应该将StringEnd()放入我的语法中,或者使用可选的arg parseAll = True。如果我从我的代码中删除parseAll = True它可以工作,但它不会解析整个字符串。
有什么想法吗?
答案 0 :(得分:6)
您可能对使用parseString
或scanString
更感兴趣,而不是searchString
。与parseString
不同,这些函数浏览输入以查找匹配项,而不是要求输入字符串中所有内容的完全匹配。 scanString
返回一个生成器,因此对于大型输入文本,将在找到匹配项时为您提供匹配:
for toks,start,end in look_for_these.scanString(pbody):
print toks[0], start, end
searchString
只是scanString
的一个简单包装(但是会删除开始和结束位置):
for t in look_for_these.searchString(pbody):
print t[0]
答案 1 :(得分:4)
将pyparsing视为更高级的正则表达式。当你传递它parseAll=True
时,它希望匹配整个字符串,使每个字节符合语法的某些部分。但是你的语法只提到了字符串中会出现的一些单词。你必须以某种方式解释其余的。
换句话说,假设流行的单词是“parrot”,“hovercraft”,“eels”和“fjords”,你已经构建了以下正则表达式的等价物:
/^(?P<dict_words>eels|fjords|hovercraft|parrot)*$/