Extrair dados numéricos de strings é uma tarefa comum na programação Python, particularmente na limpeza de dados e na raspagem da web. Este artigo explora vários métodos eficientes e versáteis para alcançar isso, atendendo a diferentes cenários e níveis de complexidade.
Sumário
- Método 1: Aproveitando Expressões Regulares
- Método 2: Utilizando List Comprehension
- Método 3: Combinando
filter
eisdigit()
- Método 4: Expressões Regulares Avançadas para Padrões Complexos
- Lidando com Variações em Formatos de Números
- Conclusão
Método 1: Aproveitando Expressões Regulares
Expressões regulares (regex) oferecem uma abordagem poderosa e flexível, especialmente para estruturas de strings complexas. O módulo re
do Python facilita esse processo.
import re
def extract_numbers_regex(text):
"""Extrai números de uma string usando expressões regulares."""
numbers = re.findall(r'-?d+(.d+)?', text) # Combina inteiros e decimais, incluindo números negativos
return [float(num) for num in numbers]
text = "Há -12 maçãs e 3.14 laranjas, e também 12345."
numbers = extract_numbers_regex(text)
print(numbers) # Saída: [-12.0, 3.14, 12345.0]
Esta regex melhorada r'-?d+(.d+)?'
trata números negativos e decimais de forma eficaz.
Método 2: Utilizando List Comprehension
List comprehension fornece uma solução concisa e Pythonica, ideal para cenários mais simples onde os números são claramente delimitados.
def extract_numbers_list_comprehension(text):
"""Extrai inteiros de uma string usando list comprehension."""
return [int(c) for c in text if c.isdigit()]
text = "123abc456"
numbers = extract_numbers_list_comprehension(text)
print(numbers) # Saída: [1, 2, 3, 4, 5, 6]
Este método é eficiente para extrair dígitos individuais, mas pode não ser adequado para números de vários dígitos ou números com pontos decimais.
Método 3: Combinando filter
e isdigit()
Esta abordagem funcional usa filter()
e isdigit()
para uma solução clara e legível, adequada para casos mais simples.
def extract_numbers_filter(text):
"""Extrai inteiros de uma string usando filter e isdigit()."""
numbers = list(filter(str.isdigit, text))
return [int(num) for num in numbers]
text = "1a2b3c4d5"
numbers = extract_numbers_filter(text)
print(numbers) #Saída: [1, 2, 3, 4, 5]
Similar à list comprehension, este método extrai dígitos individuais e não trata formatos de números mais complexos.
Método 4: Expressões Regulares Avançadas para Padrões Complexos
Expressões regulares realmente brilham ao lidar com padrões intrincados, como números em notação científica ou com separadores de milhares.
import re
def extract_numbers_complex(text):
"""Extrai números (incluindo notação científica) de uma string usando regex."""
numbers = re.findall(r'-?d+(?:,d{3})*(?:.d+)?(?:[eE][+-]?d+)?', text)
return [float(num.replace(',', '')) for num in numbers]
text = "O preço é $1,234.56 e a quantidade é 1.23e-5. Outro preço é 100,000"
numbers = extract_numbers_complex(text)
print(numbers) # Saída: [1234.56, 1.23e-05, 100000.0]
Esta regex trata vírgulas como separadores de milhares e notação científica. O replace(',', '')
remove vírgulas antes da conversão para float.
Lidando com Variações em Formatos de Números
Para se adaptar a vários formatos, considere estes pontos:
- Números negativos: Inclua
-?
no início do seu padrão regex (por exemplo,r'-?d+'
). - Notação científica: Adicione
(?:[eE][+-]?d+)?
para lidar com expoentes (como mostrado no Método 4). - Separadores de milhares: Use
(?:,d{3})*
para combinar separadores de milhares opcionais (como mostrado no Método 4). - Símbolos monetários: Pré-processe sua string para remover símbolos monetários antes da extração, ou use uma regex mais complexa.
Conclusão
O método ideal depende da complexidade das suas strings de entrada e da precisão desejada. Para casos simples, list comprehension ou filter
podem ser suficientes. No entanto, para robustez e tratamento de diversos formatos de números, expressões regulares são inestimáveis.