Máscara de CPF (em tempo real)
No evento input do campo: tira tudo que não é dígito, limita a 11 e insere a pontuação progressivamente. Como roda a cada tecla, a máscara aparece enquanto o usuário digita.
// CPF
el.value = el.value.replace(/\D/g, '').slice(0, 11)
.replace(/(\d{3})(\d)/, '$1.$2').replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');const el = document.querySelector('#cpf');
el.addEventListener('input', () => {
el.value = el.value.replace(/\D/g, '').slice(0, 11)
.replace(/(\d{3})(\d)/, '$1.$2').replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
});Máscara de CNPJ (numérico e alfanumérico)
O CNPJ alfanumérico mantém letras maiúsculas nas 12 posições da base; só os 2 verificadores são dígitos. A máscara força toUpperCase() e aceita A–Z e 0–9.
// CNPJ alfanumérico (mantém letras maiúsculas)
el.value = el.value.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 14)
.replace(/^(.{2})(.)/, '$1.$2').replace(/^(.{2}\..{3})(.)/, '$1.$2')
.replace(/^(.{2}\..{3}\..{3})(.)/, '$1/$2').replace(/(.{4})(\d{1,2})$/, '$1-$2');Resultado: 12.ABC.345/01DE-35. Para o CNPJ só-numérico clássico (11.222.333/0001-81) o mesmo código funciona — números são um subconjunto de A–Z0–9.
Os regex de formato
Para validar (não formatar) que uma string já está no formato certo, use os padrões abaixo. Eles checam o formato, nunca o dígito verificador.
CPF (com máscara) ^\d{3}\.\d{3}\.\d{3}-\d{2}$
CPF (só dígitos) ^\d{11}$
CNPJ numérico (máscara) ^\d{2}\.\d{3}\.\d{3}/\d{4}-\d{2}$
CNPJ alfanumérico ^[A-Z0-9]{2}\.[A-Z0-9]{3}\.[A-Z0-9]{3}/[A-Z0-9]{4}-\d{2}$
CNPJ alfa (só dígitos) ^[A-Z0-9]{12}\d{2}$Cuidados
- Máscara não valida o dígito. Formatar e casar com regex confirma o formato; não diz se os verificadores fecham. Quem confere o DV é a função do validar CPF / validar CNPJ. É o erro nº 1 de quem copia regex da internet.
- Guarde sem máscara. Persista só os dígitos (CPF) ou os 14 caracteres limpos (CNPJ) e aplique a máscara apenas na exibição. Antes de salvar, rode
.replace(/\D/g, '')no CPF ou.replace(/[./-]/g, '').toUpperCase()no CNPJ. - Sequências repetidas (
111.111.111-11) passam na máscara e no regex de formato — são barradas só na validação do dígito. - Válido ≠ existe. Nem o formato nem o DV dizem se o número foi emitido a alguém de verdade.