Este artigo explica como usar expressões regulares para extrair datas e horas de dados de texto em Python. Expressões regulares são uma ferramenta poderosa que permite detectar de forma eficiente cadeias de caracteres com formatos específicos através de correspondência de padrões. Neste artigo, cobriremos desde os conceitos básicos até as aplicações mais avançadas de expressões regulares, demonstrando como fazer uma correspondência precisa de datas e horas com exemplos específicos em Python.
O que é uma expressão regular
Uma expressão regular (Regular Expression) é uma cadeia de caracteres especial usada para especificar padrões de texto. Ela pode ser utilizada para representar combinações específicas de caracteres ou repetições, sendo empregada em buscas, substituições e extrações de texto. As expressões regulares são amplamente utilizadas nas áreas de programação e processamento de texto como uma ferramenta eficiente e flexível para manipulação de dados.
Módulo de expressões regulares do Python
No Python, o módulo padrão para trabalhar com expressões regulares é o módulo “re”. Usando este módulo, você pode realizar facilmente operações como busca, substituição, divisão e correspondência de cadeias de caracteres. Abaixo, apresentamos a utilização básica e as principais funções desse módulo.
Uso básico
Para usar expressões regulares, primeiro você deve importar o módulo “re”. Em seguida, você cria o padrão da expressão regular e usa-o para realizar as operações desejadas sobre as cadeias de caracteres.
import re
# Compilando o padrão da expressão regular
pattern = re.compile(r'\d{4}-\d{2}-\d{2}')
# Realizando a correspondência
match = pattern.match('2023-06-16')
if match:
print("Correspondência encontrada:", match.group())
Principais funções
re.match()
: Verifica se o início da cadeia de caracteres corresponde ao padrão.re.search()
: Busca em toda a cadeia e retorna a primeira correspondência encontrada.re.findall()
: Retorna todas as subcadeias que correspondem ao padrão em uma lista.re.sub()
: Substitui as subcadeias que correspondem ao padrão por outra cadeia.
Correspondência de datas
Para corresponder a datas, o padrão da expressão regular varia de acordo com o formato da data. Aqui, vamos explicar usando o formato de data mais comum, que é o “YYYY-MM-DD”. Este formato é composto pelo ano (4 dígitos), mês (2 dígitos) e dia (2 dígitos).
Correspondência básica de datas
O padrão de expressão regular a seguir corresponde a uma data no formato “YYYY-MM-DD”.
import re
# Criando o padrão de expressão regular
date_pattern = re.compile(r'\b\d{4}-\d{2}-\d{2}\b')
# Texto de exemplo
text = "A data de hoje é 2023-06-16."
# Realizando a correspondência
matches = date_pattern.findall(text)
if matches:
print("Datas encontradas:", matches)
else:
print("Nenhuma data encontrada.")
Este padrão corresponde a quatro dígitos (\\d{4}), seguidos de um hífen (-), dois dígitos (\\d{2}), outro hífen e, finalmente, dois dígitos (\\d{2}). O código \b
indica uma fronteira de palavra, garantindo que não haja outros caracteres ao redor da data.
Exemplo avançado: Correspondência de múltiplos formatos de data
Se você precisar corresponder a várias formas de data, pode combinar vários padrões. Por exemplo, para incluir também os formatos “YYYY/MM/DD” ou “YYYY.MM.DD”, use o seguinte padrão:
# Combinação de múltiplos padrões para expressões regulares
date_pattern = re.compile(r'\b\d{4}[-/\.]\d{2}[-/\.]\d{2}\b')
# Texto de exemplo
text = "A data de hoje é 2023-06-16, ontem foi 2023/06/15 e amanhã será 2023.06.17."
# Realizando a correspondência
matches = date_pattern.findall(text)
if matches:
print("Datas encontradas:", matches)
else:
print("Nenhuma data encontrada.")
Este padrão reconhece os delimitadores hífen (-), barra (/), ou ponto (.) entre os componentes da data.
Correspondência de horas
Para corresponder a horas, a expressão regular varia conforme o formato do horário. Vamos explicar com o formato comum “HH:MM:SS”, que consiste em horas (2 dígitos), minutos (2 dígitos) e segundos (2 dígitos).
Correspondência básica de horas
O seguinte padrão de expressão regular corresponde a uma hora no formato “HH:MM:SS”.
import re
# Criando o padrão de expressão regular
time_pattern = re.compile(r'\b\d{2}:\d{2}:\d{2}\b')
# Texto de exemplo
text = "A hora atual é 14:30:45."
# Realizando a correspondência
matches = time_pattern.findall(text)
if matches:
print("Horas encontradas:", matches)
else:
print("Nenhuma hora encontrada.")
Este padrão corresponde a dois dígitos (\\d{2}), seguidos de dois pontos (:), novamente dois dígitos, outro dois pontos e, finalmente, dois dígitos. O código \b
indica uma fronteira de palavra, garantindo que não haja outros caracteres ao redor da hora.
Exemplo avançado: Correspondência de formatos de 24 horas e 12 horas
Quando você precisa corresponder tanto horários no formato de 24 horas quanto no formato de 12 horas, pode expandir o padrão para incluir as notações AM/PM.
# Padrão para horas no formato 24 horas e 12 horas
time_pattern = re.compile(r'\b((1[0-2]|0?[1-9]):[0-5][0-9](\s?[APap][Mm])?|([01][0-9]|2[0-3]):[0-5][0-9])\b')
# Texto de exemplo
text = "A hora atual é 14:30, a reunião da manhã é às 10:00 AM, e a reunião da tarde é às 02:00 PM."
# Realizando a correspondência
matches = time_pattern.findall(text)
if matches:
print("Horas encontradas:", [match[0] for match in matches])
else:
print("Nenhuma hora encontrada.")
Este padrão reconhece os seguintes formatos de hora:
- Horas no formato de 24 horas (exemplo: 14:30)
- Horas no formato de 12 horas (exemplo: 10:00 AM, 02:00 PM)
Exemplo avançado: Conversão de formato de data e hora
Aqui, vamos mostrar como usar expressões regulares para extrair datas e horas e convertê-las para um formato diferente. Vamos converter datas e horas do formato “YYYY-MM-DD HH:MM:SS” para o formato “MM/DD/YYYY hh:mm AM/PM”.
Extração de data e hora
Primeiro, extraímos a data e a hora de um texto usando expressões regulares.
import re
# Criando o padrão de expressão regular
datetime_pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})')
# Texto de exemplo
text = "O evento começa em 2023-06-16 14:30:45."
# Realizando a correspondência
match = datetime_pattern.search(text)
if match:
year, month, day, hour, minute, second = match.groups()
print("Data e hora extraídas:", match.group())
else:
print("Data e hora não encontradas.")
Implementação da conversão de formato
Agora, vamos converter a data e a hora extraídas para o formato “MM/DD/YYYY hh:mm AM/PM”.
# Determinando AM/PM
hour = int(hour)
if hour >= 12:
period = "PM"
if hour > 12:
hour -= 12
else:
period = "AM"
if hour == 0:
hour = 12
# Convertendo para o novo formato
formatted_datetime = f"{month}/{day}/{year} {hour:02}:{minute} {period}"
print("Data e hora convertidas:", formatted_datetime)
Este código converte horas no formato de 24 horas para o formato de 12 horas e adiciona AM/PM ao novo formato.
Exercícios: Extração de datas e horas
Para aprimorar seu entendimento sobre extração de datas e horas com expressões regulares, resolva os seguintes exercícios. A prática com esses problemas ajudará você a melhorar suas habilidades.
Exercício 1: Extração de uma única data
Crie uma expressão regular para extrair datas no formato “YYYY-MM-DD” do seguinte texto:
text = "A data limite é 2024-07-20. A data de início do projeto foi 2024-06-01."
Exemplo de resposta
import re
date_pattern = re.compile(r'\b\d{4}-\d{2}-\d{2}\b')
dates = date_pattern.findall(text)
print("Datas extraídas:", dates)
Exercício 2: Extração de múltiplas horas
Crie uma expressão regular para extrair todas as horas no formato “HH:MM:SS” do seguinte texto:
text = "O café da manhã será às 07:30:00, o almoço às 12:00:00 e o jantar às 19:45:00."
Exemplo de resposta
import re
time_pattern = re.compile(r'\b\d{2}:\d{2}:\d{2}\b')
times = time_pattern.findall(text)
print("Horas extraídas:", times)
Exercício 3: Extração e conversão de formato de data e hora
Extraia a data e a hora no formato “YYYY-MM-DD HH:MM:SS” do seguinte texto e converta para o formato “MM/DD/YYYY hh:mm AM/PM”.
text = "A reunião começará em 2024-06-16 14:30:45."
Exemplo de resposta
import re
# Criando o padrão de expressão regular
datetime_pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})')
# Realizando a correspondência
match = datetime_pattern.search(text)
if match:
year, month, day, hour, minute, second = match.groups()
# Determinando AM/PM
hour = int(hour)
if hour >= 12:
period = "PM"
if hour > 12:
hour -= 12
else:
period = "AM"
if hour == 0:
hour = 12
# Convertendo para o novo formato
formatted_datetime = f"{month}/{day}/{year} {hour:02}:{minute} {period}"
print("Data e hora convertidas:", formatted_datetime)
else:
print("Data e hora não encontradas.")
Erros comuns e como corrigir
Ao usar expressões regulares, você pode se deparar com alguns erros comuns. Entendê-los e corrigi-los adequadamente pode melhorar a precisão e a eficiência das suas expressões regulares.
Erro 1: Correspondência gananciosa excessiva
A correspondência gananciosa (greedy matching) tenta corresponder ao maior número possível de caracteres. Isso pode levar a uma correspondência inesperada.
Solução: Usar correspondência preguiçosa
Você pode usar a correspondência preguiçosa (lazy matching) para garantir que apenas a menor parte necessária seja correspondida. Adicione um ponto de interrogação, como *?
ou +?
, para tornar o padrão preguiçoso.
import re
text = "Start123End456End"
pattern = re.compile(r'Start.*?End')
matches = pattern.findall(text)
print("Resultado da correspondência preguiçosa:", matches)
Erro 2: Uso incorreto de caracteres de escape
Se você usar caracteres especiais (como .
ou *
) diretamente em uma expressão regular, ela pode não corresponder corretamente ao que você espera.
Solução: Usar caracteres de escape corretamente
Quando for usar caracteres especiais diretamente, você deve escapar deles com uma barra invertida (\
).
import re
text = "O nome do arquivo é example.txt."
pattern = re.compile(r'example\.txt')
matches = pattern.findall(text)
print("Resultado do uso de caracteres de escape:", matches)
Erro 3: Queda de desempenho devido à complexidade do padrão
Padrões de expressões regulares muito complexos podem causar queda de desempenho e aumentar o tempo de execução.
Solução: Otimizar o padrão
Projete padrões de forma mais simples e eficiente para melhorar o desempenho. Evite grupos de captura desnecessários e procure corresponder o mínimo possível.
import re
# Padrão complexo
complex_pattern = re.compile(r'(\d{1,4})-?(\d{1,2})-?(\d{1,2})')
# Padrão otimizado
optimized_pattern = re.compile(r'\d{1,4}-\d{1,2}-\d{1,2}')
Erro 4: Mal-entendido do resultado da correspondência
Se você não entender corretamente o resultado da correspondência das expressões regulares, pode acabar obtendo resultados inesperados.
Solução: Usar objetos de correspondência
Use objetos de correspondência para acessar as subcadeias correspondentes ou grupos de captura de maneira precisa.
import re
text = "A data de hoje é 2024-07-20."
pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2})')
match = pattern.search(text)
if match:
year, month, day = match.groups()
print(f"Data extraída: Ano={year}, Mês={month}, Dia={day}")
else:
print("Data não encontrada.")
Conclusão
As expressões regulares são ferramentas poderosas para realizar correspondências eficientes de cadeias de caracteres com formatos específicos, como datas e horas. Usando o módulo “re” do Python, você pode facilmente realizar operações complexas de manipulação de texto. Neste artigo, cobrimos desde o uso básico de expressões regulares até a correspondência específica de datas e horas, incluindo exemplos avançados, exercícios e soluções para erros comuns. Ao aplicar expressões regulares de maneira eficaz, você pode melhorar significativamente a precisão e a eficiência no processamento de dados.