在Python中逐步执行正则表达式模式匹配:

时间:2013-08-19 23:01:48

标签: python regex conditional-statements

在python中:

  1. 条件限制中不允许分配。
  2. 正则表达式匹配的状态是根据返回的匹配对象确定的,该匹配对象还包含其他匹配信息。
  3. 现在说我们希望匹配10或15中的特定模式,我们最终会出现像这样的混乱:

    m = pat1.match(buffer)
    if m:    
        tok = tok1
        val = m.group(0)
    else:
        m = pat2.match(buffer)
        if m:
            tok = tok2 
            val = m.group(0)
        else:
            m = pat3.match(buffer)
            if m:
                tok = tok3
                val = m.group(0)
                # extra processing here and there - makes looping unsuitable
            else:
                m = pat4.match(buffer)
                if m:
                    tok = tok4
                    val = m.group(0)
                else:    
                    # ... keep indenting 
    

    我们真的希望得到如下内容:

    if match ... pat1:
        tok = 
        val = 
    elif match ... pat2:
        tok = 
        val = 
    elif match ... pat3:
        tok = 
        val = 
    ...
    

    (可以使用其他语言完成,可能使用以下功能:条件中的赋值,标准匹配对象的副作用,带引用args的不同形式的匹配函数......)

    我们可以使用循环来运行模式,但这不合适 如果每场比赛的处理有变化。

    那么:是否有任何好的pythonic方法可以将匹配条件保持在同一水平?!

1 个答案:

答案 0 :(得分:4)

成对遍历令牌和模式,以便您可以调整以下内容:

for pat, token in zip([pat1, pat2, pat3], ['tok1', 'tok2', 'tok3']):
    m = pat.match(buffer)
    if m:
        val = m.group(0)
        tok = token1
        break

想法是你在模式之前建立一个表 - >值:

tests = [
    (re.compile('([a-z]{2})'), 'func1'),
    (re.compile('(a{5}'), 'token2')
]

for pattern, token in tests:
    m = pattern.match(buffer)
    if m: 
        # whatever

这可以进一步扩展为提供一个可调用的,它可以将编译的对象和缓冲区作为参数,并从中做任何想做的事情并返回一个值。

例如:

def func1(match, buf):
    print 'entered function'
    return int(buf) * 50

tests = [ 
    (re.compile('\d+'), func1)
]

for pattern, func in tests:
    m = pattern.match(buffer)
    if m:
        result = func(m, buffer)