【问题标题】:Return string with first match for a regex, handling case where there is no match返回正则表达式第一个匹配的字符串,处理不匹配的情况
【发布时间】:2016-07-26 01:19:34
【问题描述】:

我想获得正则表达式的第一个匹配项。

在这种情况下,我有一个列表:

text = 'aa33bbb44'
re.findall('\d+',text)

['33', '44']

我可以提取列表的第一个元素:

text = 'aa33bbb44'
re.findall('\d+',text)[0]

'33'

但这只有在至少有一个匹配时才有效,否则我会得到一个错误:

text = 'aazzzbbb'
re.findall('\d+',text)[0]

IndexError: 列表索引超出范围

在这种情况下我可以定义一个函数:

def return_first_match(text):
    try:
        result = re.findall('\d+',text)[0]
    except Exception, IndexError:
        result = ''
    return result

有没有一种方法可以在不定义新函数的情况下获得该结果?

【问题讨论】:

  • 对我来说,接受的答案不起作用。我不得不删除数组索引访问并改用len(re.findAll)==0 check。

标签: python regex


【解决方案1】:

您可以通过添加|$'' 默认值嵌入到您的正则表达式中:

>>> re.findall('\d+|$', 'aa33bbb44')[0]
'33'
>>> re.findall('\d+|$', 'aazzzbbb')[0]
''
>>> re.findall('\d+|$', '')[0]
''

也适用于其他人指出的re.search

>>> re.search('\d+|$', 'aa33bbb44').group()
'33'
>>> re.search('\d+|$', 'aazzzbbb').group()
''
>>> re.search('\d+|$', '').group()
''

【讨论】:

  • 太好了,search/.group 比 findall/[0] 有什么优势吗?
  • @LuisRamonRamirezRodriguez 它可以在找到匹配项后立即停止,不必处理其余文本,也不必存储所有匹配项。所以效率更高。此外,正如@TimPeters 所说,它确实“就是你想要的”。当您或其他人在某些时候阅读它并想知道“为什么使用findall?”时,这可能是一个优势?
【解决方案2】:

如果只需要第一个匹配项,则使用re.search 而不是re.findall

>>> m = re.search('\d+', 'aa33bbb44')
>>> m.group()
'33'
>>> m = re.search('\d+', 'aazzzbbb')
>>> m.group()
Traceback (most recent call last):
  File "<pyshell#281>", line 1, in <module>
    m.group()
AttributeError: 'NoneType' object has no attribute 'group'

那么你可以使用m作为检查条件:

>>> m = re.search('\d+', 'aa33bbb44')
>>> if m:
        print('First number found = {}'.format(m.group()))
    else:
        print('Not Found')


First number found = 33

【讨论】:

    【解决方案3】:

    我会选择:

    r = re.search("\d+", ch)
    result = return r.group(0) if r else ""
    

    re.search 无论如何都只会在字符串中查找 first 匹配项,所以我认为它比使用 findall 更能让您的意图更加清晰。

    【讨论】:

      【解决方案4】:

      您根本不应该使用 .findall() - .search() 是您想要的。它会找到最左边的匹配项,这就是您想要的(如果不存在匹配项,则返回 None)。

      m = re.search(pattern, text)
      result = m.group(0) if m else ""
      

      您是否要将其放入函数中取决于您。如果没有找到匹配项,不寻常想要返回一个空字符串,这就是为什么没有内置类似的东西。不可能对 .search() 自己是否找到匹配项感到困惑(它如果没有,则返回 None,否则返回 SRE_Match 对象。

      【讨论】:

        【解决方案5】:

        你可以这样做:

        x = re.findall('\d+', text)
        result = x[0] if len(x) > 0 else ''
        

        请注意,您的问题与正则表达式并不完全相关。相反,如果数组中没有元素,你如何安全地找到它。

        【讨论】:

        • 我会在这里用简单的 'x' 替换 'len(x) > 0'。
        【解决方案6】:

        如果更多的输入数据不包含您想要的部分,也许这会更好一些,因为除了成本更高。

        def return_first_match(text):
            result = re.findall('\d+',text)
            result = result[0] if result else ""
            return result
        

        【讨论】:

          【解决方案7】:

          只需将结果分配给一个变量,然后迭代该变量

           text = 'aa33bbb44'
           result=re.findall('\d+',text)
           for item in result:
               print(item)
          

          【讨论】:

            猜你喜欢
            • 2016-11-29
            • 1970-01-01
            • 2013-11-04
            • 1970-01-01
            • 2012-03-11
            • 2023-03-13
            • 2020-04-24
            • 2012-09-17
            相关资源
            最近更新 更多