在Python中匹配组

时间:2010-03-31 15:21:06

标签: python regex

在Python中是否有办法在不明确创建匹配对象的情况下访问匹配组(或另一种方式来美化下面的示例)?

这是一个澄清我对这个问题的动机的例子:

遵循Perl代码

if    ($statement =~ /I love (\w+)/) {
  print "He loves $1\n";
}
elsif ($statement =~ /Ich liebe (\w+)/) {
  print "Er liebt $1\n";
}
elsif ($statement =~ /Je t\'aime (\w+)/) {
  print "Il aime $1\n";
}

翻译成Python

m = re.search("I love (\w+)", statement)
if m:
  print "He loves",m.group(1)
else:
  m = re.search("Ich liebe (\w+)", statement)
  if m:
    print "Er liebt",m.group(1)
  else:
    m = re.search("Je t'aime (\w+)", statement)
    if m:
      print "Il aime",m.group(1)

看起来很尴尬(if-else-cascade,匹配对象创建)。

5 个答案:

答案 0 :(得分:35)

您可以创建一个返回调用匹配的布尔结果的小类,保留匹配的组以供后续检索:

import re

class REMatcher(object):
    def __init__(self, matchstring):
        self.matchstring = matchstring

    def match(self,regexp):
        self.rematch = re.match(regexp, self.matchstring)
        return bool(self.rematch)

    def group(self,i):
        return self.rematch.group(i)


for statement in ("I love Mary", 
                  "Ich liebe Margot", 
                  "Je t'aime Marie", 
                  "Te amo Maria"):

    m = REMatcher(statement)

    if m.match(r"I love (\w+)"): 
        print "He loves",m.group(1) 

    elif m.match(r"Ich liebe (\w+)"):
        print "Er liebt",m.group(1) 

    elif m.match(r"Je t'aime (\w+)"):
        print "Il aime",m.group(1) 

    else: 
        print "???"

答案 1 :(得分:18)

效率低下但看起来更简单:

m0 = re.match("I love (\w+)", statement)
m1 = re.match("Ich liebe (\w+)", statement)
m2 = re.match("Je t'aime (\w+)", statement)
if m0:
  print "He loves",m0.group(1)
elif m1:
  print "Er liebt",m1.group(1)
elif m2:
  print "Il aime",m2.group(1)

Perl的问题是隐式更新了一些隐藏变量。这在Python中很难实现,因为你需要有一个赋值语句来实际更新任何变量。

重复次数较少(效率更高)的版本是:

pats = [
    ("I love (\w+)", "He Loves {0}" ),
    ("Ich liebe (\w+)", "Er Liebe {0}" ),
    ("Je t'aime (\w+)", "Il aime {0}")
 ]
for p1, p3 in pats:
    m= re.match( p1, statement )
    if m:
        print p3.format( m.group(1) )
        break

一些Perl民众喜欢的小变化:

pats = {
    "I love (\w+)" : "He Loves {0}",
    "Ich liebe (\w+)" : "Er Liebe {0}",
    "Je t'aime (\w+)" : "Il aime {0}",
}
for p1 in pats:
    m= re.match( p1, statement )
    if m:
        print pats[p1].format( m.group(1) )
        break

这几乎不值得一提,除了它有时会出现在Perl程序员身上。

答案 2 :(得分:4)

这不是正则表达式解决方案。

alist={"I love ":""He loves"","Je t'aime ":"Il aime","Ich liebe ":"Er liebt"}
for k in alist.keys():
    if k in statement:
       print alist[k],statement.split(k)[1:]

答案 3 :(得分:1)

你可以创建一个辅助函数:

def re_match_group(pattern, str, out_groups):
    del out_groups[:]
    result = re.match(pattern, str)
    if result:
        out_groups[:len(result.groups())] = result.groups()
    return result

然后像这样使用它:

groups = []
if re_match_group("I love (\w+)", statement, groups):
    print "He loves", groups[0]
elif re_match_group("Ich liebe (\w+)", statement, groups):
    print "Er liebt", groups[0]
elif re_match_group("Je t'aime (\w+)", statement, groups):
    print "Il aime", groups[0]

它有点笨拙,但它完成了工作。

答案 4 :(得分:0)

SELECT @NSQL开始,并引入assignment expressions (PEP 572)<div class="g-signin2" data-onsuccess="onSignIn"></div> <script> function onSignIn(googleUser) { var profile = googleUser.getBasicProfile(); window.location.href = '`enter code here`'; } function signOut() { var auth2 = gapi.auth2.getAuthInstance(); auth2.signOut().then(function () { console.log('User signed out.'); }); } </script> 运算符),我们现在可以在变量中捕获条件值Python 3.8(将其全部{{1 }}),以检查是否不是:=,然后在条件主体内重新使用它:

re.search(pattern, statement)