【问题标题】:ParseException: Expected end of textParseException:预期的文本结尾
【发布时间】:2011-09-26 19:55:17
【问题描述】:

我正在尝试使用 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 中的常见问题解答,如果我希望解析器解析整个字符串,我应该将 StringEnd() 放入我的语法中,或者使用可选的 arg parseAll=True。如果我从我的代码中删除 parseAll=True 它可以工作,但它不会解析整个字符串。

有什么想法吗?

【问题讨论】:

  • >> “但是,它会引发 ParseException,而不是抱怨预期文本结束。” - 正如您在 pyparsing 常见问题解答中看到的那样 - 它引发 exaclty ParseException 抱怨文本结束是预期的。这就是它的运作方式——这是他的行为。不要以为找到INVALID语法后就可以让pyparsing解析所有文本。

标签: python parsing pyparsing


【解决方案1】:

您可能对使用scanStringsearchString 更感兴趣,而不是parseString。与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]

【讨论】:

    【解决方案2】:

    将 pyparsing 视为更高级的正则表达式。当您传递parseAll=True 时,它希望匹配整个字符串,将每个字节限定为语法的某些部分。但是,您的语法仅提及将出现在字符串中的一些单词。您必须以某种方式考虑其余部分。

    换句话说,假设流行词是“parrot”、“hovercraft”、“eels”和“fjords”,您已经构建了一个等价于以下正则表达式:

    /^(?P<dict_words>eels|fjords|hovercraft|parrot)*$/
    

    【讨论】:

    • 嘿,谢谢。所以基本上我必须构造另一个语法来匹配字符串的其余部分,我可以通过设置结果名称来区分两个匹配的集合,对吧?
    • 是的,您还可以告诉 pyparsing 忽略符合某些条件的部分文本,这样您最终只会在解析的输出中得到有价值的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多