首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >替代`match = re.match();if match:...`习惯用法?

替代`match = re.match();if match:...`习惯用法?
EN

Stack Overflow用户
提问于 2009-07-20 08:40:43
回答 10查看 23.6K关注 0票数 34

如果您想检查某些内容是否与正则表达式匹配,如果匹配,则打印第一组,您可以这样做。

代码语言:javascript
运行
复制
import re
match = re.match("(\d+)g", "123g")
if match is not None:
    print match.group(1)

这完全是书呆子气,但是中间的match变量有点烦人。

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

代码语言:javascript
运行
复制
if($blah ~= /(\d+)g/){
    print $1
}

来自this reddit comment

代码语言:javascript
运行
复制
with re_context.match('^blah', s) as match:
    if match:
        ...
    else:
        ...

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

代码语言:javascript
运行
复制
#!/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))

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

如果您可以在没有匹配的情况下跳过with语句代码块的执行,那就太好了,这将简化为..

代码语言:javascript
运行
复制
with rematch("(\d+)g", "123") as m:
    print(m.group(1)) # only executed if the match occurred

根据我从PEP 343推断的结果,这似乎是不可能的

有什么想法吗?正如我所说的,这真的是微不足道的烦恼,几乎到了代码高尔夫的地步。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2019-04-27 23:23:40

启动Python 3.8,引入assignment expressions (PEP 572) (:=运算符),我们现在可以在变量match中捕获条件值re.match(r'(\d+)g', '123g'),以便检查它是否不是None,然后在条件主体中重用它:

代码语言:javascript
运行
复制
>>> 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))
...
>>>
票数 3
EN

Stack Overflow用户

发布于 2009-07-20 09:06:09

我不认为这是微不足道的。如果我经常写这样的代码,我不想在我的代码周围散布多余的条件。

这有点奇怪,但您可以使用迭代器来完成此操作:

代码语言:javascript
运行
复制
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))

奇怪的是,它对没有迭代的东西使用迭代器--它更接近于条件,乍一看,它可能会为每个匹配生成多个结果。

上下文管理器不能完全跳过它的托管函数,这看起来确实很奇怪;虽然这不是"with“的明确用例之一,但它似乎是一个自然的扩展。

票数 12
EN

Stack Overflow用户

发布于 2012-12-05 20:05:16

另一个很好的语法是这样的:

代码语言:javascript
运行
复制
header = re.compile('(.*?) = (.*?)$')
footer = re.compile('(.*?): (.*?)$')

if header.match(line) as m:
    key, value = m.group(1,2)
elif footer.match(line) as m
    key, value = m.group(1,2)
else:
    key, value = None, None
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1152385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档