🌗 ← Índice
Data: 09/07/2026
Nível: Intermediário
String é o tipo de dado que mais aparece em código real — logs, nomes de arquivo, respostas de API, saída pro usuário. Hoje tu vai dominar manipulação de texto e aprender regex: o canivete suíço dos padrões.
nome = "Hugo"
idade = 30
print(f"Olá, {nome}! Você tem {idade} anos.")
# Alinhamento e largura
print(f"|{'Esquerda':<15}|{'Centro':^15}|{'Direita':>15}|")
# |Esquerda | Centro | Direita|
# Números
pi = 3.14159265
print(f"PI = {pi:.2f}") # PI = 3.14
print(f"R${12345.6:,.2f}") # R$12,345.60
# Datas
from datetime import datetime
hoje = datetime.now()
print(f"{hoje:%d/%m/%Y %H:%M}") # 09/07/2026 08:00
texto = " Hugo Costa da Silva "
# Limpeza
print(texto.strip()) # "Hugo Costa da Silva" (remove bordas)
print(texto.lower()) # " hugo costa da silva "
print(texto.upper()) # " HUGO COSTA DA SILVA "
print(texto.title()) # " Hugo Costa Da Silva "
# Busca e substituição
print("Hugo" in texto) # True
print(texto.find("Costa")) # 7 (índice onde começa)
print(texto.replace("Hugo", "HB")) # " HB Costa da Silva "
print(texto.startswith(" Hugo")) # True
# Divisão e junção (as mais usadas!)
partes = texto.strip().split(" ") # ["Hugo", "Costa", "da", "Silva"]
junto = "-".join(partes) # "Hugo-Costa-da-Silva"
# Verificação de tipo
"123".isdigit() # True
"abc123".isalnum() # True
"Hugo".isalpha() # True
# CSV caseiro
linha = "Hugo,30,Brasília,Python"
dados = linha.split(",") # ["Hugo", "30", "Brasília", "Python"]
# Reconstrói com outro separador
pipe = "|".join(dados) # "Hugo|30|Brasília|Python"
# Log real
log = '2026-07-09 08:30:15 ERRO: conexão recusada'
partes = log.split(" ", 3) # Divide em no máximo 4 partes
# ['2026-07-09', '08:30:15', 'ERRO:', 'conexão recusada']
Regex (Regular Expression) é uma mini-linguagem pra buscar padrões em texto.
import re
texto = "Contato: hugo@email.com ou hugo.costa@hbstudio.com.br"
# Encontrar todos os emails
emails = re.findall(r'[\w.]+@[\w.]+\.\w+', texto)
print(emails) # ['hugo@email.com', 'hugo.costa@hbstudio.com.br']
# Verificar se existe
if re.search(r'email', texto):
print("Tem 'email' no texto")
# Substituir padrão
anonimizado = re.sub(r'[\w.]+@[\w.]+\.\w+', '[EMAIL]', texto)
print(anonimizado) # Contato: [EMAIL] ou [EMAIL]
log = "2026-07-09 08:30:15 ERRO: conexão recusada no host 192.168.1.1"
match = re.search(
r'(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+(\w+):\s+(.+)',
log
)
if match:
print(f"Data: {match.group(1)}") # 2026-07-09
print(f"Hora: {match.group(2)}") # 08:30:15
print(f"Nível: {match.group(3)}") # ERRO
print(f"Mensagem: {match.group(4)}") # conexão recusada...
| Padrão | Significado | Exemplo |
|---|
|---|---|---|
| `\d` | Dígito (0-9) | `\d{3}` → "123" |
|---|---|---|
| `\w` | Letra, número ou `_` | `\w+` → "hugo_costa" |
| `\s` | Espaço, tab, newline | `\s+` → qualquer espaço |
| `.` | Qualquer caractere | `h.g` → "hug", "hag" |
| `+` | 1 ou mais | `\d+` → "12345" |
| `*` | 0 ou mais | `\d*` → "" ou "123" |
| `?` | 0 ou 1 | `a?` → "" ou "a" |
| `{n,m}` | Entre n e m vezes | `\d{2,4}` → "12", "1234" |
| `[abc]` | a, b ou c | `[Hh]ugo` → "Hugo" ou "hugo" |
| `^` | Início da string | `^Olá` → começa com Olá |
| `$` | Fim da string | `fim$` → termina com fim |
| `()` | Grupo de captura | `(Hugo)\s(Costa)` |
import re
log = """
2026-07-09 08:30:15 INFO: servidor iniciado na porta 8080
2026-07-09 08:31:02 ERRO: conexão recusada (timeout 5s)
2026-07-09 08:32:45 WARN: disco com 90% de uso
2026-07-09 08:35:00 INFO: 150 requisições processadas
"""
# Extrai nível e mensagem de cada linha
padrao = r'(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+(\w+):\s+(.+)'
registros = re.findall(padrao, log)
erros = [r for r in registros if r[2] == "ERRO"]
print(f"Total de erros: {len(erros)}")
for data, hora, nivel, msg in erros:
print(f" [{data} {hora}] {msg}")
Crie validar_cpf(cpf) que verifica se a string tem 11 dígitos (ignore . e -). Use regex e re.sub.
import re
# Teu código aqui
Dado um texto, extraia todas as URLs (http://... ou https://...) com re.findall.
texto = "Visite https://www.python.org e também http://example.com/path"
# Teu código aqui — deve retornar lista com as 2 URLs
Crie normalizar(nome) que:
# Teu código aqui
Crie um analisador de arquivo de log que:
1. Lê um arquivo servidor.log (crie um de exemplo)
2. Extrai data, hora, nível e mensagem de cada linha com regex
3. Agrupa por nível (INFO, ERRO, WARN)
4. Exibe um resumo: total de linhas, quantos erros, avisos
5. Lista só os ERROS com data/hora
# Teu código aqui
import re
def validar_cpf(cpf):
# Remove tudo que não for dígito
digitos = re.sub(r'\D', '', cpf)
return len(digitos) == 11
print(validar_cpf("123.456.789-00")) # True
print(validar_cpf("123.456")) # False
import re
def extrair_urls(texto):
return re.findall(r'https?://[^\s]+', texto)
texto = "Visite https://www.python.org e também http://example.com/path"
print(extrair_urls(texto))
# ['https://www.python.org', 'http://example.com/path']
def normalizar(nome):
nome = nome.strip().title()
# Remove acentos (simplificado)
mapa = {'Á':'A', 'À':'A', 'Ã':'A', 'Â':'A', 'É':'E', 'Ê':'E',
'Í':'I', 'Ó':'O', 'Ô':'O', 'Õ':'O', 'Ú':'U', 'Ç':'C'}
for acento, sem in mapa.items():
nome = nome.replace(acento, sem)
return nome
print(normalizar(" hugo côsta da sálva "))
# "Hugo Costa Da Salva"
import re
# Criar log de exemplo
with open("servidor.log", "w") as f:
f.write("""2026-07-09 08:30:15 INFO: servidor iniciado
2026-07-09 08:31:02 ERRO: conexao recusada
2026-07-09 08:32:45 WARN: disco 90%
2026-07-09 08:35:00 INFO: 150 reqs
2026-07-09 08:40:11 ERRO: timeout API
""")
# Analisar
padrao = r'(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+(\w+):\s+(.+)'
with open("servidor.log") as f:
linhas = f.readlines()
registros = []
for linha in linhas:
match = re.search(padrao, linha)
if match:
registros.append(match.groups())
# Resumo
total = len(registros)
erros = [r for r in registros if r[2] == "ERRO"]
warns = [r for r in registros if r[2] == "WARN"]
infos = [r for r in registros if r[2] == "INFO"]
print(f"Total de linhas: {total}")
print(f"ERRO: {len(erros)} | WARN: {len(warns)} | INFO: {len(infos)}")
print("\n--- ERROS ---")
for data, hora, _, msg in erros:
print(f" [{data} {hora}] {msg}")
**Próxima aula:** P10 — Desafio Final Mês 1 (projeto integrador!)