如何在Python中搜索正则表达式匹配?

如何在Python中搜索正则表达式匹配?,python,regex,switch-statement,Python,Regex,Switch Statement,我需要对多个正则表达式尝试一个字符串(独占-意味着匹配其中一个正则表达式的字符串不能匹配任何其他正则表达式),并根据匹配的正则表达式执行不同的代码段。我目前拥有的是: m = firstre.match(str) if m: # Do something m = secondre.match(str) if m: # Do something else m = thirdre.match(str) if m: # Do something different from

我需要对多个正则表达式尝试一个字符串(独占-意味着匹配其中一个正则表达式的字符串不能匹配任何其他正则表达式),并根据匹配的正则表达式执行不同的代码段。我目前拥有的是:

m = firstre.match(str)
if m:
    # Do something

m = secondre.match(str)
if m:
    # Do something else

m = thirdre.match(str)
if m:
    # Do something different from both
除了丑陋之外,即使在匹配了其中一个正则表达式(比如firstre)之后,该代码也会匹配所有正则表达式,这是低效的。我尝试使用:

elif m = secondre.match(str)
但学会了在if语句中不允许赋值


有没有一种优雅的方式来实现我想要的

一些想法,没有一个是好的,但可能很适合您的代码:

将代码放在一个单独的函数中,即
MatchRegex()
,该函数返回它匹配的正则表达式。这样,在函数内部,您可以在匹配第一个(或第二个)正则表达式后使用return,这意味着您失去了效率

当然,您可以始终使用嵌套的
if
语句:

m = firstre.match(str)
if m:
   # Do something
else:
    m = secondre.match(str)
    ...

我真的看不出有什么理由不使用嵌套的
if
s。它们很容易理解,而且效率很高。我选择它们只是因为它们的简单性。

这可能有点过分设计解决方案,但您可以将它们作为一个单独的regexp与命名组组合,并查看哪个组匹配。可以将其封装为帮助器类:

def doit( s ):

    # with some side-effect on a
    a = [] 

    def f1( s, m ):
        a.append( 1 )
        print 'f1', a, s, m

    def f2( s, m ):
        a.append( 2 )
        print 'f2', a, s, m

    def f3( s, m ):
        a.append( 3 )
        print 'f3', a, s, m

    re1 = re.compile( 'one' )
    re2 = re.compile( 'two' )
    re3 = re.compile( 'three' )


    func_re_list = (
        ( f1, re1 ), 
        ( f2, re2 ), 
        ( f3, re3 ),
    )
    for myfunc, myre in func_re_list:
        m = myre.match( s )
        if m:
            myfunc( s, m )
            break


doit( 'one' ) 
doit( 'two' ) 
doit( 'three' ) 
import re
class MultiRe(object):
    def __init__(self, **regexps):
        self.keys = regexps.keys()
        self.union_re = re.compile("|".join("(?P<%s>%s)" % kv for kv in regexps.items()))

    def match(self, string, *args):
        result = self.union_re.match(string, *args)
        if result:
            for key in self.keys:
                if result.group(key) is not None:
                    return key

也许早点回来

def doit(s):
    m = re1.match(s)
    if m:
        # Do something
        return

    m = re2.match(s)
    if m:
        # Do something else
        return

    ...
Ants Aasma的答案也很好。如果你更喜欢少搭建脚手架,你可以使用

re=re.compile(r''(?x)#设置详细标志
(?P-fo+)
|(?P ba+r)
|#……其他替代方案。。。
''')
def doit(s):
m=重新匹配
如果m.group('foo'):
#做点什么
elif m.group(“酒吧”):
#做点别的
...

我已经做了很多了。它速度快,可与
re.finditer

配合使用elif,以防您只需要正则表达式匹配的真/假:

if regex1.match(str):
    # do stuff
elif regex2.match(str):
    # and so on
你可以用

def do_first(str, res, actions):
  for re,action in zip(res, actions):
    m = re.match(str)
    if m:
      action(str)
      return
例如,假设您已经定义了

def do_something_1(str):
  print "#1: %s" % str

def do_something_2(str):
  print "#2: %s" % str

def do_something_3(str):
  print "#3: %s" % str

firstre  = re.compile("foo")
secondre = re.compile("bar")
thirdre  = re.compile("baz")
那就叫它

do_first("baz",
         [firstre,        secondre,       thirdre],
         [do_something_1, do_something_2, do_something_3])

这是一个很好的应用程序,用于未记录但非常有用的类。

+1用于纯粹的pythonic awebomeness。就个人而言,我会将元组列表放在for语句之外,例如
match_functions=((f1,re1),(f2,re2),…)
和do
对于match_函数中的myfunc,myre:
别忘了添加“break”为了保存,我尝试与列表的其余部分进行匹配。根据注释的建议和真实示例进行编辑。我最终实现了类似的解决方案。在我的例子中,我能够将4个案例中的3个重构为一个函数。因此,我直接匹配了第一个正则表达式,如果不匹配,则遍历其他3个正则表达式,并使用适当的参数调用函数。为了根据正则表达式调用具有不同参数的函数,我使用了(regex:(arg1,arg2))的dict。代码(至少)比以前更加优雅了。非常感谢。我认为他需要regex.match(str)的返回值。从我的角度来看,这看起来像工程。我觉得代码并不容易理解。如果有几百个正则表达式呢?超过10码的代码几乎不可读。@kibitzer:在这种情况下,设计一个通用的解决方案是有意义的。或者在预计增长到这一水平的情况下。不是每次你都要写3个嵌套的if。
def do_something_1(str):
  print "#1: %s" % str

def do_something_2(str):
  print "#2: %s" % str

def do_something_3(str):
  print "#3: %s" % str

firstre  = re.compile("foo")
secondre = re.compile("bar")
thirdre  = re.compile("baz")
do_first("baz",
         [firstre,        secondre,       thirdre],
         [do_something_1, do_something_2, do_something_3])