区分pyparsing中的匹配项 [英] Distinguish matches in pyparsing

查看:71
本文介绍了区分pyparsing中的匹配项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用pyparsing解析一些单词和一些数字.简单的权利.

I want to parse some words and some numbers with pyparsing. Simple right.

from pyparsing import *

A = Word(nums).setResultsName('A')
B = Word(alphas).setResultsName('B')
expr = OneOrMore(A | B)

result = expr.parseString("123 abc 456 7 d")
print result

上面的代码显示['123', 'abc', '456', '7', 'd'].所以一切正常.现在,我想对这些解析后的值做一些工作.对于此任务,我需要知道它们是否匹配AB.有没有办法区分这两者.

The code above prints ['123', 'abc', '456', '7', 'd']. So everything worked. Now I want to do some work with these parsed values. For this task, I need to know if they matched A or B. Is there a way to distinguish between these two.

经过研究,我发现的唯一发现是ParseResults类的items方法.但是它仅返回[('A', '7'), ('B', 'd')],仅返回最后两个匹配项.

The only thing what I found after some research was the items method of the ParseResults class. But it only returns [('A', '7'), ('B', 'd')], only the last two matches.

我的计划/目标如下:

for elem in result:
    if elem.is_of_type('A'):
        # do stuff
    elif elem.is_of_type('B'):
        # do something else

如何区分AB?

推荐答案

具有getName()的不错的工作.您还可以使用标记显式修饰返回的令牌,以指示进行了哪些匹配:

Nice job with getName(). You can also explicitly decorate the returned tokens with a marker, indicating which match was made:

def makeDecoratingParseAction(marker):
    def parse_action_impl(s,l,t):
        return (marker, t[0])
    return parse_action_impl

A = Word(nums).setParseAction(makeDecoratingParseAction("A"))
B = Word(alphas).setParseAction(makeDecoratingParseAction("B"))
expr = OneOrMore(A | B)

result = expr.parseString("123 abc 456 7 d")
print result.asList()

赠予:

[('A', '123'), ('B', 'abc'), ('A', '456'), ('A', '7'), ('B', 'd')]

现在,您可以遍历返回的元组,并且每个元组都用适当的标记标记.

Now you can iterate over the returned tuples, and each one is labelled with the appropriate marker.

您可以更进一步,使用一个类来捕获类型和特定于类型的后解析逻辑,然后将该类作为表达式的解析动作传递.这将在返回的ParseResults中创建类的实例,然后您可以使用某种execdoIt方法直接执行这些实例:

You can take this a step further and use a class to capture both the type and the type-specific post-parse logic, and then pass the class as the expression's parse action. This will create instances of the classes in the returned ParseResults, which you can then execute directly with some sort of exec or doIt method:

class ResultsHandler(object):
    """Define base class to initialize location and tokens.
       Call subclass-specific post_init() if one is defined."""
    def __init__(self, s,locn,tokens):
        self.locn = locn
        self.tokens = tokens
        if hasattr(self, "post_init"):
            self.post_init()

class AHandler(ResultsHandler):
    """Handler for A expressions, which contain a numeric string."""
    def post_init(self):
        self.int_value = int(self.tokens[0])
        self.odd_even = ("EVEN","ODD")[self.int_value % 2]
    def doIt(self):
        print "An A-Type was found at %d with value %d, which is an %s number" % (
                self.locn, self.int_value, self.odd_even)

class BHandler(ResultsHandler):
    """Handler for B expressions, which contain an alphabetic string."""
    def post_init(self):
        self.string = self.tokens[0]
        self.vowels_count = sum(self.string.lower().count(c) for c in "aeiou")
    def doIt(self):
        print "A B-Type was found at %d with value %s, and contains %d vowels" % (
                self.locn, self.string, self.vowels_count)


# pass expression-specific handler classes as parse actions
A = Word(nums).setParseAction(AHandler)
B = Word(alphas).setParseAction(BHandler)
expr = OneOrMore(A | B)

# parse string and run handlers
result = expr.parseString("123 abc 456 7 d")
for handler in result:
    handler.doIt()

打印:

An A-Type was found at 0 with value 123, which is an ODD number
A B-Type was found at 4 with value abc, and contains 1 vowels
An A-Type was found at 8 with value 456, which is an EVEN number
An A-Type was found at 12 with value 7, which is an ODD number
A B-Type was found at 14 with value d, and contains 0 vowels

这篇关于区分pyparsing中的匹配项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆