7

Как извлечь числа из строки в Python?

1

Я бы хотел извлечь все числа, содержащиеся в строке. Что лучше использовать для этой цели: регулярные выражения или метод isdigit()?

Пример:

line = "hello 12 hi 89"

Результат:

[12, 89]

Какое решение будет более эффективным и простым в реализации?

5 ответ(ов)

8

Я бы использовал регулярные выражения:

>>> 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]

Обратите внимание: это не сработает для отрицательных целых чисел.

1

Если вы уверены, что в строке будет только одно число, например, '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

В последнем примере происходит конкатенация двух чисел, что может быть не тем, что вы ожидаете. Поэтому убедитесь, что в строке действительно только одно число, иначе вам могут понадобиться другие методы для обработки строки.

0

Предполагаю, вы хотите работать с числами с плавающей запятой, а не только с целыми, поэтому я бы сделал что-то вроде этого:

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
0

Чтобы поймать различные числовые паттерны, полезно делать запросы с использованием разных шаблонов.

Устанавливаем все шаблоны для ловли различных интересующих числовых паттернов:

  • Для поиска чисел с запятыми, например, 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
0

Вы искали решение для удаления масок из строк, в частности, из бразильских номеров телефонов. Эта тема не была полностью раскрыта, но вдохновила меня. Вот мое решение:

>>> phone_number = '+55(11)8715-9877'
>>> ''.join([n for n in phone_number if n.isdigit()])
'551187159877'

Этот код проходит через каждую цифру в строке phone_number и собирает только числовые символы, игнорируя все остальные. В результате получается строка с полным номером телефона без масок.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь