Como lidar com caracteres acentuados em sistemas e formulários
Muita gente trava na hora de fazer inputs, queries de banco de dados ou manipulação de strings quando aparecem acentos. O problema não é tão complexo assim, mas os sintomas aparecem do jeito mais chato possível. O texto chega cortado, o caractere vira um quadrado, e a consulta simplesmente não encontra nada que você sabe que está no banco.
Por que atendê los tem acento costuma dar problema
O cerne da questão é encoding. Quando o navegador envia um formulário com "São Paulo" e o servidor espera ISO-8859-1, ele lê o "ã" como dois bytes diferentes. O resultado é algo como "So Paulo" ou "S%C3%A3o Paulo" dependendo de como você inspeciona. A solução mais direta é padronizar tudo em UTF-8 desde o início — HTML, banco, APIs. Quando você configura o charset errado em apenas um elo da cadeia, o resto quebra sem avisar. Num projeto meu faz alguns anos, tinha um sistema de cadastros onde os endereços vinham de uma planilha Excel exportada em Windows-1252. A codificação do banco era UTF-8. Os acentos chegavam distorcidos e as buscas por nome de cidade simplesmente não funcionavam. A correção foi rodar um script de normalização com a função `mb_convert_encoding` do PHP, convertendo tudo para UTF-8 antes de inserir. Em vez de confiar na importação automática, eu li caractere por caractere e apliquei a conversão explicitamente. O processo levou cerca de 40 minutos num banco de 12 mil registros.
Métodos práticos para lidar com acentos
Normalização de strings: O segredo é decompor os caracteres. Um "ã" não é um caractere único, é um "a" + til. Quando você aplica a forma NFD (Normalization Form Decomposed), os acentos viram combinações separadas. Aí você consegue tratar a base e o acento independentemente. Em Python, a biblioteca `unicodedata` faz isso com uma linha: `unicodedata.normalize('NFD', texto)`. Em JavaScript, o mesmo se aplica via `.normalize('NFD')`. Depois basta remover os diacríticos com uma regex ou fatiando os primeiros bytes. Tratamento em consultas de banco: Se você trabalha com MySQL e precisa buscar "São Paulo" sem se importar com acentos, pode usar `COLLATE` com uma ordem de classificação específica. `utf8mb4_unicode_ci` ou `utf8mb4_general_ci` tratam "a" e "á" como equivalentes nas comparações. Em PostgreSQL, a função `unaccent()` do módulo contrib está instalada por padrão e remove diacríticos na hora da busca. O problema é que colunas com acentos removidos não usam índices normais, então você precisa criar um índice funcional se o volume de dados for relevante.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Validação de formulário: Campos de entrada costumam aceitar qualquer caractere que o usuário digitar. A validação deve normalizar antes de salvar. Se o seu sistema permite login com e-mail e alguém usa "joão@email.com" com acento, ao normalizar para "joao@email.com" você evita duplicidade e conflitos. Isso é especialmente importante quando a normalização acontece em etapas diferentes — o frontend pode mandar o e-mail acentado, o backend normaliza, mas o lookup no banco usa outro método. A inconsistência gera duplicados silenciosos.
Pegadinhas que ninguém conta
A primeira é sobre a diferença entre NFD e NFC. NFD decompõe, NFC compõe. Se você normaliza com NFD e esquece de recompor com NFC antes de salvar, o banco pode armazenar o mesmo caractere de duas formas diferentes. Duas linhas com "café" podem ter representações binárias distintas. A comparação direta falha. Sempre normalize para NFC no ponto final, depois de aplicar qualquer transformação. A segunda pegadinha é o caso do "ç". O cedilha não é um diacrítico composto. Ele é um caractere único no Unicode. Quando você remove acentos usando decomposição NFD, o "ç" permanece intacto. Se o seu objetivo é remover absolutamente todos os sinais gráficos especiais, precisa tratar o cedilha separadamente. Caso contrário, a busca por "racional" não encontrará "racional" com cedilha porque só um deles passa pela filtragem.
Limitações reais: A normalização por si só não resolve problemas de codificação no trânsito dos dados. Se o header HTTP do seu servidor não informa UTF-8 corretamente, a normalização roda no byte errado e produz resultado ainda mais estranho. Teste sempre com curl ou Postman para ver o charset que o servidor está declarando. Um simples `curl -I https://seusite.com.br/api/rota` já mostra se o Content-Type vem com charset ou se o cliente vai adivinhar.
Quando a normalização não basta
Existe um cenário em que remover acentos é insuficiente: entradas deliberadamente criativas. Um usuário pode digitar "Rúbia" com acento circunflexo diferente, ou "Giovanna" com um "o" que na verdade é um ô com til. A normalização combina alguns, mas não todos. Para búsquedas robustas, o ideal é criar um campo adicional de busca normalizada, não substituir o original. O campo com acentos permanece para exibição e integridade dos dados. O campo normalizado serve exclusivamente para matching. Se você está lidando com textos multilíngues e precisa de matching mais flexível, bibliotecas como `intl` no Node.js ou o ICU no Java oferecem ordenação e comparação muito mais refinadas do que uma simples remoção de acentos. Vale a pena migrar para elas quando o projeto cresce além de um único idioma com acentuação portuguesa.