返回第一个匹配正则表达式的字符串


90

我想获得正则表达式的第一场比赛。

在这种情况下,我得到了一个列表:

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。
维沙尔

Answers:


104

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

>>> 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]有任何优势?
路易斯·拉蒙·拉米雷斯·罗德里格斯

6
@LuisRamonRamirezRodriguez好吧,它可以在找到一个匹配项后立即停止,无需处理其余文本,也不必存储所有匹配项。这样更有效。此外,正如@TimPeters所说,它实际上是“您想要的”。当您或其他人有时阅读它并想知道“为什么findall使用它?”时,这可能是一个优势
Stefan Pochmann

43

如果您只需要第一个匹配项,请使用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

12

我会去:

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

re.search无论如何,它只会在字符串中查找第一个匹配项,因此我认为它的意图比使用更加清晰findall


7

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

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

是否要将其放在函数中取决于您。如果没有找到匹配项,则想返回一个空字符串是很不寻常的,这就是为什么内置了类似的东西的原因。对于是否.search()单独找到匹配项(None如果没有找到则返回,或者返回一个SRE_Match对象),我们不会感到困惑如果有)。


3

你可以做:

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

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


2
我会在这里简单地用“ x”代替“ len(x)> 0”。
乌尔夫·阿斯拉克

1

如果更多的输入数据不包含所需的数据,则这样做可能会更好一些,因为这样做的成本更高。

def return_first_match(text):
    result = re.findall('\d+',text)
    result = result[0] if result else ""
    return result
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.