Как извлечь числа из строки в Python?
Я бы хотел извлечь все числа, содержащиеся в строке. Что лучше использовать для этой цели: регулярные выражения или метод isdigit()
?
Пример:
line = "hello 12 hi 89"
Результат:
[12, 89]
Какое решение будет более эффективным и простым в реализации?
5 ответ(ов)
Я бы использовал регулярные выражения:
>>> import re
>>> re.findall(r'\d+', "hello 42 I'm a 32 string 30")
['42', '32', '30']
Этот вариант также найдет 42 в строке bla42bla
. Если вам нужны только числа, разделенные границами слов (пробел, точка, запятая), вы можете использовать \b
:
>>> re.findall(r'\b\d+\b', "he33llo 42 I'm a 32 string 30")
['42', '32', '30']
Чтобы получить список чисел вместо списка строк, можно преобразовать их в целые числа:
>>> [int(s) for s in re.findall(r'\b\d+\b', "he33llo 42 I'm a 32 string 30")]
[42, 32, 30]
Обратите внимание: это не сработает для отрицательных целых чисел.
Если вы уверены, что в строке будет только одно число, например, 'hello 12 hi'
, вы можете использовать filter
.
Вот пример для неотрицательных целых чисел:
In [1]: int(''.join(filter(str.isdigit, '200 grams')))
Out[1]: 200
In [2]: int(''.join(filter(str.isdigit, 'Counters: 55')))
Out[2]: 55
In [3]: int(''.join(filter(str.isdigit, 'more than 23 times')))
Out[3]: 23
Но будьте осторожны!!!:
In [4]: int(''.join(filter(str.isdigit, '200 grams 5')))
Out[4]: 2005
В последнем примере происходит конкатенация двух чисел, что может быть не тем, что вы ожидаете. Поэтому убедитесь, что в строке действительно только одно число, иначе вам могут понадобиться другие методы для обработки строки.
Предполагаю, вы хотите работать с числами с плавающей запятой, а не только с целыми, поэтому я бы сделал что-то вроде этого:
l = []
for t in s.split():
try:
l.append(float(t))
except ValueError:
pass
Обратите внимание, что некоторые другие решения, представленные здесь, не работают с отрицательными числами:
>>> re.findall(r'\b\d+\b', 'he33llo 42 I\'m a 32 string -30')
['42', '32', '30']
>>> '-3'.isdigit()
False
Чтобы поймать различные числовые паттерны, полезно делать запросы с использованием разных шаблонов.
Устанавливаем все шаблоны для ловли различных интересующих числовых паттернов:
- Для поиска чисел с запятыми, например, 12,300 или 12,300.00
r'[\d]+[.,\d]+'
- Для поиска дробных чисел, например, 0.123 или .123
r'[\d]*[.][\d]+'
- Для поиска целых чисел, например, 123
r'[\d]+'
Объединяем с помощью оператора или ( |
) в один шаблон с несколькими условиями ИЛИ.
(Примечание: Сложные паттерны помещайте в начало, иначе простые паттерны будут возвращать части сложного паттерна вместо полного совпадения).
p = '[\d]+[.,\d]+|[\d]*[.][\d]+|[\d]+'
Далее мы проверим наличие шаблона с помощью re.search()
, затем вернем итерабельный список совпадений. Наконец, мы напечатаем каждое совпадение, используя нотацию с квадратными скобками для выбора значения из объекта совпадения.
s = 'he33llo 42 I\'m a 32 string 30 444.4 12,001'
if re.search(p, s) is not None:
for catch in re.finditer(p, s):
print(catch[0]) # catch - это объект совпадения
Возвращает:
33
42
32
30
444.4
12,001
Вы искали решение для удаления масок из строк, в частности, из бразильских номеров телефонов. Эта тема не была полностью раскрыта, но вдохновила меня. Вот мое решение:
>>> phone_number = '+55(11)8715-9877'
>>> ''.join([n for n in phone_number if n.isdigit()])
'551187159877'
Этот код проходит через каждую цифру в строке phone_number
и собирает только числовые символы, игнорируя все остальные. В результате получается строка с полным номером телефона без масок.
Есть ли в Python метод подстроки 'contains' для строк?
Как получить подстроку из строки в Python?
Объединение двух столбцов текста в DataFrame pandas
Вывод строки в текстовый файл
Преобразование всех строк в списке в целые числа