如何在 Python 中组合 switch-case 和正则表达式

问题描述 投票:0回答:6

我想通过将字符串与正则表达式序列匹配来处理它。当我试图避免嵌套的 if-then 时,我正在考虑 switch-case。如何用Python编写以下结构?谢谢你

switch str:
   case match(regex1):
       # do something
   case match(regex2):
       # do sth else

我知道 Perl 允许人们这样做。有Python吗?

python switch-statement
6个回答
9
投票

首先考虑为什么Python中没有case语句。所以重置你的大脑并忘记它们。

您可以使用对象类、函数装饰器或使用函数字典来实现相同或更好的结果。

这是一个简单的例子:

#!/usr/bin/env python
import re

def hat(found):
    if found: print "found a hat"
    else: print "no hat"

def cat(found):
    if found: print "found a cat"
    else: print "no cat"

def dog(found):    
    if found: print "found a dog"
    else: print "no dog"

st="""
Here is the target string
with a hat and a cat
no d o g 
end
"""

patterns=['hat', 'cat', 'dog']
functions=[hat,cat,dog]

for pattern,case in zip(patterns,functions):
    print "pattern=",pattern
    case(re.search(pattern,st))

C 风格的 case / switch 语句也“失败”,例如:

   switch(c) {
       case 'a':
       case 'b':
       case 'c':  do_abc();
                  break;
       ... other cases...
   }

使用元组和可调用列表,您可以获得类似的行为:

st="rat kitten snake puppy bug child"

def proc1(st): print "cuddle the %s" % st
def proc2(st): print "kill the %s" % st
def proc3(st): print "pick-up the %s" % st
def proc4(st): print "wear the %s" % st
def proc5(st): print "dispose of the %s" %st
def default(st): print "%s not found" % st

dproc={ ('puppy','kitten','child'): 
            [proc3, proc1], 
        ('hat','gloves'): 
            [proc3, proc4], 
        ('rat','snake','bug'): 
            [proc2, proc3, proc5]}

for patterns,cases in dproc.iteritems():
    for pattern in patterns:
        if re.search(pattern,st):
            for case in cases: case(pattern)
        else: default(pattern)    
        print

这使得找到的物品的顺序正确:1)抱起孩子,拥抱孩子; 2) 杀掉老鼠,捡起老鼠……用 C switch 语句以可理解的语法来完成同样的事情是很困难的。

还有许多其他方法可以模仿 C switch 语句。这是使用函数装饰器的一个(对于整数):

case = {}

def switch_on(*values):
    def case_func(f):
        case.update((v, f) for v in values)
        return f
    return case_func

@switch_on(0, 3, 5)
def case_a(): print "case A"

@switch_on(1,2,4)
def case_b(): print "case B"

def default(): print "default"

for i in (0,2,3,5,22):
    print "Case: %i" % i
    try: 
        case[i]()
    except KeyError:
        default()

套用 Larry Wall、Tom Christiansen、Jon Orwant 在 Programming Perl 中关于理解 Perl 上下文的说法:

除非你使用 Python 语言原生的习惯用法,否则你的 Python 编程将会很痛苦......


5
投票

快速搜索显示了之前提出的“类似问题”,并有多种解决方法。 最喜欢的解决方案是 Mizard import re class Re(object): def __init__(self): self.last_match = None def match(self,pattern,text): self.last_match = re.match(pattern,text) return self.last_match def search(self,pattern,text): self.last_match = re.search(pattern,text) return self.last_match gre = Re() if gre.match(r'foo',text): # do something with gre.last_match elif gre.match(r'bar',text): # do something with gre.last_match else: # do something else



1
投票
pyswitch

(免责声明:我是作者)。 有了它,您可以执行以下操作,这与您在问题中给出的示例非常接近: from pyswitch import Switch mySwitch = Switch() @myswitch.caseRegEx(regex1) def doSomething(matchObj, *args, **kwargs): # Do Something return 1 @myswitch.caseRegEx(regex2) def doSomethingElse(matchObj, *args, **kwargs): # Do Something Else return 2 rval = myswitch(stringYouWantToSwitchOn)

我链接的 URL 上给出了一个更全面的示例。  pyswitch 不仅限于切换正则表达式。  在内部,pyswitch 使用类似于其他人上面给出的示例的调度系统。  我只是厌倦了每次需要那种调度系统时都必须一遍又一遍地重写相同的代码框架,所以我编写了 pyswitch。


1
投票

import re # The patterns r1 = "spam" r2 = "eggs" r3 = "fish" def doSomething1(): return "Matched spam." def doSomething2(): return "Matched eggs." def doSomething3(): return "Matched fish." def default(): return "No match." def match(r, s): mo = re.match(r, s) try: return mo.group() except AttributeError: return None def delegate(s): try: action = { match(r1, s): doSomething1, match(r2, s): doSomething2, match(r3, s): doSomething3, }[s]() return action except KeyError: return default()

结果

>>> delegate("CantBeFound") 0: 'No match.' >>> delegate("spam") 1: 'Matched spam.' >>> delegate("eggs") 2: 'Matched eggs.' >>> delegate("fish") 3: 'Matched fish.'



0
投票

如果您指的是 Perl

给定 / 当输入 switch 语句时

,那么在 Python 中实现这并不是一件容易的事。您需要实现“智能匹配”和其他重要的 Perl 习惯用法。你不妨用 Perl 写任何东西? 如果您指的是C 风格的 switch 语句,那么相比之下,这些相对来说是微不足道的。最推荐使用字典调度方法,例如:

import re def case_1(): print "case 1" return 1 def case_2(): print "case 2" return 2 def case_3(): print "case 3" return 3 def default(): print "None" return 0 dispatch= { 'a': case_1, 'g': case_2, 'some_other': case_3, 'default': default } str="abcdefg" r=[dispatch[x]() if re.search(x,str) else dispatch['default']() for x in ['a','g','z'] ] print "r=",r

Python从3.10版本开始支持switch语句。  下面是使用正则表达式和 Python 新的 switch 语句支持的示例:

0
投票

这将采用一个带有数字和时间单位的字符串,例如“15d”是15天。 正则表达式将 15 和 d 分开,然后对单位执行 switch 语句。

此代码将 Polar 的样式持续时间格式(更多信息
此处

)转换为 timedelta 格式。

当然,您可以将任何类型的正则表达式与这样的 switch 语句一起使用。 我推荐命名组,因为它使阅读代码更容易。

© www.soinside.com 2019 - 2024. All rights reserved.