替代`match = re.match(); 如果匹配:...`成语?

dbr*_*dbr 33 python idioms

如果你想检查某些东西是否与正则表达式匹配,如果是,打印第一组,你可以...

import re
match = re.match("(\d+)g", "123g")
if match is not None:
    print match.group(1)
Run Code Online (Sandbox Code Playgroud)

这完全是迂腐的,但中间match变量有点烦人..

像Perl这样的语言通过为匹配组创建新的$1.. $9变量来实现这一点,比如..

if($blah ~= /(\d+)g/){
    print $1
}
Run Code Online (Sandbox Code Playgroud)

这个reddit评论,

with re_context.match('^blah', s) as match:
    if match:
        ...
    else:
        ...
Run Code Online (Sandbox Code Playgroud)

..我认为这是一个有趣的想法,所以我写了一个简单的实现:

#!/usr/bin/env python2.6
import re

class SRE_Match_Wrapper:
    def __init__(self, match):
        self.match = match

    def __exit__(self, type, value, tb):
        pass

    def __enter__(self):
        return self.match

    def __getattr__(self, name):
        if name == "__exit__":
            return self.__exit__
        elif name == "__enter__":
            return self.__name__
        else:
            return getattr(self.match, name)

def rematch(pattern, inp):
    matcher = re.compile(pattern)
    x = SRE_Match_Wrapper(matcher.match(inp))
    return x
    return match

if __name__ == '__main__':
    # Example:
    with rematch("(\d+)g", "123g") as m:
        if m:
            print(m.group(1))

    with rematch("(\d+)g", "123") as m:
        if m:
            print(m.group(1))
Run Code Online (Sandbox Code Playgroud)

(理论上可以将此功能修补到_sre.SRE_Match对象中)

with如果没有匹配可以跳过语句代码块的执行会很好,这会简化这个...

with rematch("(\d+)g", "123") as m:
    print(m.group(1)) # only executed if the match occurred
Run Code Online (Sandbox Code Playgroud)

..但这似乎是不可能的,因为我可以从PEP 343中推断出来

有任何想法吗?正如我所说,这真是微不足道的烦恼,几乎到了代码高尔夫的程度.

Gle*_*ard 12

我不认为这是微不足道的.如果我经常编写类似的代码,我不想在我的代码周围添加冗余条件.

这有点奇怪,但您可以使用迭代器执行此操作:

import re

def rematch(pattern, inp):
    matcher = re.compile(pattern)
    matches = matcher.match(inp)
    if matches:
        yield matches

if __name__ == '__main__':
    for m in rematch("(\d+)g", "123g"):
        print(m.group(1))
Run Code Online (Sandbox Code Playgroud)

奇怪的是,它正在使用迭代器来处理不迭代的东西 - 它更接近条件,乍一看,它似乎会为每个匹配产生多个结果.

上下文管理器不能完全跳过其托管函数,这似乎很奇怪; 虽然这并不是"with"的用例之一,但它似乎是一种自然的延伸.

  • 如果Python允许在表达式中赋值,如C:"如果x = y():","如果不是(x = y():";它会直接处理它,这将是很好的. (3认同)

Xav*_*hot 5

开始Python 3.8,并引入赋值表达式(PEP 572)(运算符),我们现在可以捕获变量中的:=条件值,以便检查它是否不存在,然后在条件体内重新使用它:re.match(r'(\d+)g', '123g')matchNone

>>> if match := re.match(r'(\d+)g', '123g'):
...   print(match.group(1))
... 
123
>>> if match := re.match(r'(\d+)g', 'dddf'):
...   print(match.group(1))
...
>>>
Run Code Online (Sandbox Code Playgroud)