【问题标题】:trying to use "or" operator elegantly [duplicate]试图优雅地使用“或”运算符[重复]
【发布时间】:2021-05-13 18:29:52
【问题描述】:

我有一小部分正则表达式用于生成新字符串:

someinput = "some/very/long/string"

changedinput = re.match("(.*\/)", str(thisDir)).group(1)[:-1]

我使用.group(1)[:-1]获取实际的字符串,这段代码需要适用于各种字符串。

如果这里的输入字符串是"blbalba",则不匹配,正则表达式将返回Nonetype,因此,调用grou()时出现此错误:

'NoneType' object has no attribute 'group'

我可以用这样的结构来解决:

someinput = "some/very/long/string"
tmp = re.match("(.*\/)", str(bla))# .group(1)[:-1]
if (tmp):
    changedinput = tmp.group(1)[:-1]
else:
    changedinput = ""    

虽然我需要 行代码来实现这个非常简单的结构,但确实让我很恼火。 于是我开始在 python 中寻找类似 elvis 构造函数的东西,并找到了 "or" 运算符。 然后我想我可以做这样的事情:

someinput = "some/very/long/string"
changedinput = re.match("(.*\/)", str(someinput)).group(1)[:-1] or ""

这里的原因是,如果没有匹配,那么 group() 调用将再次抛出相同的错误。

我有什么方法可以做到这一点,只需几行代码,以一种不错的 Python 方式?

【问题讨论】:

  • 最后四行可以替换为changedinput = tmp.group(1)[:-1] if tmp else ""
  • 您也可以不使用正则表达式(.*)\/ 捕获\/。这样,第 1 组就已经是正确的了
  • or 顺便说一句,将无法在此上下文中处理所有测试用例。

标签: python regex


【解决方案1】:

你可以使用赋值表达式:

changedinput = (tmp.group(1)[:-1] 
                if (tmp := re.match("(.*\/)", str(someinput))
                else "")

re.match 被调用,它的返回值被分配给tmp,然后在布尔上下文中进行评估。如果为真,则tmp 的值用于调用group,而不是第二次调用re.match

【讨论】:

    【解决方案2】:

    你可以这样做:

    changedinput = tmp.group(1)[:-1] if tmp else ""
    

    这也更“pythonic”,因为它的代码更少,但效率较低,因为您调用了两次re.match()

    changedinput = re.match("(.*\/)", str(someinput)).group(1)[:-1] if re.match("(.*\/)", str(someinput)) else ""
    

    【讨论】:

    • 是的,这很好用。有一秒钟我有点紧张 python 没有懒惰的评估,但这有效
    • 太棒了。如果您觉得这回答了您的问题,请不要忘记接受它作为答案,以便其他人也可以使用它:)
    猜你喜欢
    • 2011-12-11
    • 2019-04-12
    • 2020-12-28
    • 2016-09-27
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 2013-05-27
    相关资源
    最近更新 更多