在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,匹配对象创建)。
答案 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)