CodePráticov3.6.0
PHPCNPJ 2026

Regex para CNPJ alfanumérico: validar formato não é validar o CNPJ

Uma expressão regular é ótima para responder “este texto tem o formato esperado?”. Ela não consegue responder sozinha “os dígitos verificadores estão corretos?” nem “este CNPJ existe na Receita Federal?”. Para o CNPJ alfanumérico, separar essas três validações evita código enganoso.

Regex para CNPJ alfanumérico sem máscara

O novo CNPJ continua com 14 posições. As 12 primeiras podem conter números de 0 a 9 e letras maiúsculas de A a Z. As duas últimas posições são dígitos verificadores e continuam exclusivamente numéricas.

Para um valor já normalizado, a expressão regular é:

^[A-Z0-9]{12}[0-9]{2}$

Leitura da regex:

  • ^ — início do valor;
  • [A-Z0-9]{12} — exatamente 12 caracteres alfanuméricos;
  • [0-9]{2} — exatamente 2 dígitos numéricos para os DVs;
  • $ — fim do valor.
Compatibilidade: essa mesma regex aceita os CNPJs numéricos antigos, porque os algarismos de 0 a 9 também pertencem ao conjunto [A-Z0-9].

Regex para CNPJ com máscara

Para validar exatamente o padrão visual AA.AAA.AAA/AAAA-DV:

^[A-Z0-9]{2}\.[A-Z0-9]{3}\.[A-Z0-9]{3}\/[A-Z0-9]{4}-[0-9]{2}$

Os pontos e a barra precisam ser escapados na expressão porque têm significado especial em regex ou porque queremos deixar o padrão explícito.

Exemplos que correspondem ao formato:

00.000.000/E08G-12
12.ABC.345/01DE-35
04.252.011/0001-10

Exemplos que não correspondem:

12.ABC.345/01DE-AB   // DV precisa ser numérico
12.ABC.345/01D*-35   // * não é permitido
12.ABC.345/01DE-3    // falta um dígito
12.ABC.345-01DE-35   // separadores fora do padrão

Exemplo em PHP

Uma abordagem segura é normalizar somente os separadores conhecidos e depois validar a estrutura.

function normalizarCnpj(string $cnpj): string
{
    return strtoupper(
        str_replace(['.', '/', '-', ' '], '', trim($cnpj))
    );
}

function temFormatoCnpj(string $cnpj): bool
{
    $cnpj = normalizarCnpj($cnpj);

    return preg_match(
        '/^[A-Z0-9]{12}[0-9]{2}$/D',
        $cnpj
    ) === 1;
}

Uso:

var_dump(temFormatoCnpj('00.000.000/E08G-12')); // true
var_dump(temFormatoCnpj('04.252.011/0001-10')); // true
var_dump(temFormatoCnpj('12.ABC.345/01DE-AB')); // false
var_dump(temFormatoCnpj('12.ABC.345/01D*-35')); // false

O modificador D do PCRE faz com que o $ corresponda somente ao fim real da string, evitando aceitar uma quebra de linha final inesperada.

Exemplo em JavaScript e TypeScript

A mesma regra pode ser usada no frontend:

const CNPJ_FORMAT_REGEX = /^[A-Z0-9]{12}[0-9]{2}$/;

function normalizarCnpj(cnpj: string): string {
  return cnpj
    .trim()
    .toUpperCase()
    .replace(/[.\/-]/g, '')
    .replace(/\s/g, '');
}

function temFormatoCnpj(cnpj: string): boolean {
  return CNPJ_FORMAT_REGEX.test(normalizarCnpj(cnpj));
}

Isso é útil para feedback imediato no formulário, mas a validação precisa ser repetida no backend. Validação de frontend é conveniência de UX, não barreira de segurança.

Por que a regex não valida o dígito verificador?

Considere este valor:

AA.AAA.AAA/AAAA-00

Ele está estruturalmente correto: tem 12 caracteres alfanuméricos e dois dígitos no final. Portanto, a regex retorna true.

Porém, aplicando o algoritmo oficial de cálculo dos DVs à base AAAAAAAAAAAA, os dígitos correspondentes são 45, não 00. Logo, o formato é válido, mas o CNPJ falha na validação dos dígitos verificadores.

É justamente por isso que não devemos criar uma função chamada validarCnpj() se ela faz apenas preg_match(). Um nome como temFormatoCnpj() comunica corretamente o que a função garante.

Para validar também os dois DVs, use a implementação completa do artigo Como validar CNPJ numérico e alfanumérico em PHP.

Os três níveis de validação

Quando alguém diz “preciso validar o CNPJ”, pode estar falando de três coisas diferentes:

  • Formato: caracteres, quantidade de posições e máscara. Regex resolve.
  • Dígito verificador: recalcular os dois DVs com o algoritmo oficial e comparar. Regex não resolve.
  • Situação cadastral: confirmar se aquele CNPJ foi atribuído e verificar sua situação na Receita Federal. Exige consulta a uma fonte cadastral.

Em formulário, normalmente faz sentido verificar formato no frontend e repetir formato + DV no backend. Quando a regra do negócio exigir existência ou situação cadastral, adicione a consulta apropriada.

Regex que parecem corretas, mas não são

1. Continuar usando apenas dígitos

^\d{14}$

Essa expressão rejeita qualquer novo CNPJ que contenha letras.

2. Usar \w

^\w{12}\d{2}$

\w não significa “letra ou número do CNPJ”. Em engines comuns ele também aceita o caractere _ e pode ter comportamento adicional conforme Unicode/configuração. Prefira declarar exatamente o conjunto aceito: [A-Z0-9].

3. Usar [A-z]

[A-z]

Isso também é incorreto. No intervalo ASCII entre Z e a existem caracteres como colchetes, barra invertida, acento circunflexo e sublinhado. Use [A-Z] depois de normalizar para maiúsculas.

4. Apagar qualquer coisa que não seja alfanumérica

preg_replace('/[^A-Z0-9]/i', '', $cnpj);

Para uma rotina de validação isso pode esconder erro de digitação. Se o usuário informar um caractere inesperado, ele pode simplesmente desaparecer. É melhor remover apenas os separadores previstos e rejeitar o restante.

Uma única regex com máscara opcional vale a pena?

É possível criar uma expressão que aceite com e sem máscara. Mas isso costuma deixar a regra menos legível e pode aceitar combinações parciais de separadores se for escrita de maneira descuidada.

Para código de produção, prefira uma destas duas estratégias:

  • normalizar a entrada e validar sempre o valor de 14 posições sem máscara;
  • ter uma regex específica para o campo mascarado e outra para o valor normalizado.

A primeira opção costuma ser mais simples quando o backend armazena o CNPJ sem pontuação.

Checklist rápido

  • aceite A-Z e 0-9 nas 12 primeiras posições;
  • mantenha os dois últimos caracteres exclusivamente numéricos;
  • normalize letras para maiúsculas;
  • não use \d{14} como regra geral;
  • não confunda regex com cálculo de DV;
  • não confunda DV válido com CNPJ cadastrado;
  • mantenha compatibilidade com CNPJs numéricos já existentes;
  • repita a validação relevante no backend.

Fontes oficiais

Referências técnicas conferidas em 12/09/2026.

Próximo artigo do cluster

O próximo passo será Como adaptar banco de dados, inputs e APIs para CNPJ alfanumérico, com um checklist de tipos de coluna, DTOs, máscaras, contratos JSON, schemas e integrações legadas.