首页 > 解决方案 > Python 在 if 语句中使用正则表达式匹配对象,然后访问像 Perl 这样的捕获组

问题描述

是否可以在 Python 中执行类似以下 Perl 代码的操作?据我所知,答案是否定的,但我想我会仔细检查。

我想在 Python 中复制的 Perl 代码:

#!/usr/bin/perl

my $line = "hello1234world";

if($line=~/hello(.*)world/) {
  print($1);
}
#prints 1234    

以下是我能想到的最接近的风格,但是在运行时我(显然)得到以下错误:

import re
line = "hello1234world"

if matchObj = re.match(r'hello(.*)world',line):
    print(matchObj.group(1))

#error: if matchObj = re.match(r'hello(.*)world',line):
#error:             ^
#error: SyntaxError: invalid syntax

以下是我能想到的最佳工作代码:

import re
line = "hello1234world"

matchObj = re.match(r'hello(.*)world',line)

if matchObj:
    print(matchObj.group(1))
#prints 1234

如果可能的话,我真的很想避免单独的变量声明和 if 语句。

标签: pythonregexperl

解决方案


可以只打印(假定的)捕获并使用异常来处理group调用方法时的情况 on None,当没有匹配时返回。如果匹配失败时确实无事可做,则通过With Statement Context Manager (3.4+)进行一行

from contextlib import suppress

with suppress(Exception):
    print( re.match(r'hello(.*)world', line).group(1) )

为了避免忽略几乎肯定不应该在这里忽略的异常,比如SystemExitand KeyboardInterrupt,使用

with suppress(BaseException):
    ...

这现在是相当紧凑的,正如所要求的那样,它的行为符合预期。仅仅使用异常来缩短代码可能被认为是错误的,但也许会有更多的用途。

正如评论中提到的,从 3.8 开始就有了赋值表达式

if match := re.match(r'hello(.*)world', line):
    print( match.group(1) )

它几乎直接匹配激励语义。然而,这个较新的特性引起了一些敏感的讨论,而仅仅使用它来缩短代码可能会造成混淆和误导,因为它与预期的 Python 方法不同。

我想补充一点,我建议不要担心额外的几行代码,特别是要避免模仿其他语言的样式和程序流程。使用手头语言的风格和习语具有巨大的价值。


推荐阅读