【问题标题】:Pyparsing newbie setParseAction modifying tokensPyparsing 新手 setParseAction 修改令牌
【发布时间】:2012-12-01 13:37:17
【问题描述】:

我是 Pyparsing 的新手(对 Python 也很陌生)。我试图将我的问题简化为最简单的形式,以说明出了什么问题(到了我可能根本不需要 Pyparsing 的地步!)

假设我有一个由字母和数字组成的字符串,例如“b7 z4 a2 d e c3”。总是有一个字母,但数字是可选的。我想把它解析成它的单个元素,然后处理它们,但是如果有一个没有数字的裸字母,那么更改它以便它后面有“默认”数字 1 会很方便。然后我可以以一致的方式处理每个元素。我想我可以用 setparseAction 来做到这一点,如下:

from pyparsing import *
teststring = "a2 b5 c9 d e z"
expected_letter = Word("ABCDEFGabcdefgzZxy", exact=1)
expected_number = Word(nums)
letter_and_number = expected_letter + expected_number
bare_letter = expected_letter
bare_letter.setParseAction( lambda s,l,t:  t.append("1") )
elements =  letter_and_number | bare_letter
line = OneOrMore(elements)
print line.parseString(teststring)

不幸的是,t.append() 并没有达到我的预期,即在已解析的标记列表中添加一个“1”。相反,我得到一个错误:TypeError: 'str' object is not callable。

在这里,我可能只是太厚了,但你们中的一位专家能否让我直截了当。

谢谢

史蒂夫

【问题讨论】:

    标签: python pyparsing


    【解决方案1】:

    了解 pyparsing 的一个基本概念是它不仅仅适用于字符串列表,而是将已解析的片段组装成 ParseResults 对象。 ParseResults 是在 pyparsing 中定义的丰富数据类型,可以作为列表访问,如果存在已从具有已定义结果名称的 ParserElement 解析的标记,则可以作为 dict 或对象访问。

    但是,虽然 ParseResults 在设计时考虑到了易于访问,但它的更新方式受到限制。在 pyparsing 内部,每个匹配的表达式都会创建一个小的 ParseResults 对象;如果这是大型表达式的一部分,则该表达式使用 += 运算符将这些片段累积到一个大型 ParseResults 中。

    在您的情况下,您可以通过创建一个包含“1”的小型 ParseResults 并将其添加到 t 来附加到传入的 ParseResults:

    t += ParseResults("1")
    

    不幸的是,这不能作为 lambda - 你可以尝试

    lambda s,l,t: t.__iadd__(ParseResults("1"))
    

    但这感觉有点太聪明了。

    您还可以重新考虑一下您的解析器,以利用 Optional 类。将您的尾随数字视为可选元素,您可以为其定义一个默认值,以防该元素丢失。我认为您可以通过以下方式定义您想要的内容:

    >>> letter = Word(alphas,exact=1)
    >>> digit = Word(nums,exact=1)
    >>> teststring= "a2 b5 c9 d e z"
    >>> letter_and_digit = Combine(letter + Optional(digit, default="1"))
    >>> print (sum(letter_and_digit.searchString(teststring)))
    ['a2', 'b5', 'c9', 'd1', 'e1', 'z1']
    

    Combine 用于将单独的字母和数字重新连接成字符串,否则每个匹配项看起来像 ['a','2'], ['b','5'] 等。

    (通常,searchString 返回一个 ParseResults 对象列表,它看起来像一个单元素列表的列表。通过将 searchString 的结果传递给sum,这会将它们全部添加到一个 ParseResults 字符串中。)

    【讨论】:

    • 啊,是的,这很有意义!当我打印出解析结果时,它们看起来像一个普通的列表,所以我想我可以用通常的方式追加。我也错过了 Optional 允许默认设置的事实,它提供了一个更整洁的整体解决方案。它将适用于我的实际程序,这比这里的精简版本要复杂一些。非常感谢您的帮助....以及 Pyparsing 本身!史蒂夫。
    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 2015-03-09
    • 2016-08-21
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多