Возвращает строку с первым соответствием Regex
Я хочу получить первое совпадение регулярного выражения.
В этом случае я получил список:
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
Есть ли способ получить этот результат без определения новой функции?
Ответы
Ответ 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()
''
Ответ 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
Вы не должны использовать .findall()
вообще - .search()
- это то, что вы хотите. Он находит самое левое совпадение, которое вы хотите (или возвращает None
, если совпадение не существует).
m = re.search(pattern, text)
result = m.group(0) if m else ""
Если вы хотите поместить это в функцию, зависит от вас. Необязательно возвращать пустую строку, если совпадение не найдено, поэтому ничего подобного не встроено. Невозможно запутаться в том, что сам .search()
находит совпадение (он возвращает None
, если он не был 't или объект SRE_Match
, если это так).
Ответ 4
Я бы пошел с:
r = re.search("\d+", ch)
result = return r.group(0) if r else ""
re.search все равно ищет первое совпадение в строке, поэтому я думаю, что это делает ваше намерение немного более понятным, чем использование findall.
Ответ 5
Вы можете сделать:
x = re.findall('\d+', text)
result = x[0] if len(x) > 0 else ''
Обратите внимание, что ваш вопрос не совсем связан с регулярным выражением. Скорее, как вы можете безопасно найти элемент из массива, если он не имеет.
Ответ 6
Возможно, это будет немного лучше, если большее количество входных данных не будет содержать ваш желаемый фрагмент, потому что, кроме того, он имеет большую стоимость.
def return_first_match(text):
result = re.findall('\d+',text)
result = result[0] if result else ""
return result