Ferramentas gratuitas para desenvolvedores. Nenhum dado real de pessoas é consultado ou armazenado.Como funciona o algoritmo do CPF →
Fundamentos

Regex de CNPJ numérico e alfanumérico

Expressões regulares para CNPJ numérico e alfanumérico, com e sem máscara, CPF ou CNPJ, Google Forms, HTML pattern e máscara de input que aceita letras.

Roberto GuerraPublicado em 05 de outubro de 2026Editar no GitHub

Toda regex de CNPJ escrita antes de 2026 tem uma premissa que deixou de valer: a de que o número só contém dígitos. Com o CNPJ alfanumérico, as 12 primeiras posições aceitam letras de A a Z, e uma expressão com \d{14} passa a recusar números válidos. Este guia reúne as expressões para os dois formatos, com e sem máscara, e mostra as adaptações para Google Forms, planilhas e o atributo pattern do HTML.

Numérico com e sem máscara

Para sistemas que, por algum motivo, ainda só lidam com o formato numérico:

const CNPJ_NUMERICO = /^\d{14}$/;
const CNPJ_NUMERICO_MASCARA = /^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/;
const CNPJ_NUMERICO_FLEXIVEL = /^\d{2}\.?\d{3}\.?\d{3}\/?\d{4}-?\d{2}$/;

CNPJ_NUMERICO_MASCARA.test('11.222.333/0001-81'); // true
CNPJ_NUMERICO.test('11222333000181');             // true
CNPJ_NUMERICO.test('12ABC34501DE35');             // false

A barra precisa de escape (\/) dentro de um literal de regex em JavaScript, porque a barra delimita a expressão. Em strings passadas para new RegExp, em Python e no HTML, ela pode ficar sem escape. O ponto, por outro lado, precisa de escape em qualquer lugar: sozinho, ele significa “qualquer caractere”.

Em Python 3, \d aceita dígitos de outros sistemas de escrita, como os arábico-índicos. Se a entrada vem de fora, prefira [0-9] ou a flag re.ASCII.

Alfanumérico com e sem máscara

A troca é pontual: nas 12 primeiras posições, \d vira [A-Z0-9]. Os dois últimos caracteres continuam \d, porque os dígitos verificadores são sempre numéricos. Estas são as expressões da biblioteca de referência do site:

regex-cnpj.js
const CNPJ_ALFANUMERICO = /^[A-Z0-9]{12}\d{2}$/;
const CNPJ_ALFANUMERICO_MASCARA = /^[A-Z0-9]{2}\.[A-Z0-9]{3}\.[A-Z0-9]{3}\/[A-Z0-9]{4}-\d{2}$/;
const CNPJ_ALFANUMERICO_FLEXIVEL = /^[A-Z0-9]{2}\.?[A-Z0-9]{3}\.?[A-Z0-9]{3}\/?[A-Z0-9]{4}-?\d{2}$/;

CNPJ_ALFANUMERICO_MASCARA.test('12.ABC.345/01DE-35'); // true
CNPJ_ALFANUMERICO_MASCARA.test('11.222.333/0001-81'); // true: numérico também passa
CNPJ_ALFANUMERICO.test('12ABC34501DE35');             // true
CNPJ_ALFANUMERICO.test('12ABC34501DE3X');             // false: letra no dígito
CNPJ_ALFANUMERICO.test('12abc34501de35');             // false: minúsculas

Como [A-Z0-9] inclui os dígitos, a expressão alfanumérica aceita também todos os CNPJs numéricos. Não é preciso manter as duas: substitua a antiga pela nova.

As expressões aceitam só maiúsculas, e isso é proposital. O formato usa letras maiúsculas, e a recomendação é converter a entrada antes de testar, com valor.toUpperCase(), em vez de usar a flag i. Assim o valor que passa no teste é o mesmo que vai para o banco. Em Python, o equivalente é re.fullmatch(r'[A-Z0-9]{12}[0-9]{2}', valor.upper()).

Cada linguagem tem um detalhe nas âncoras. Em JavaScript, sem a flag m, $ só casa no fim do texto. Em Python e PHP, $ também casa antes de uma quebra de linha final, então "12ABC34501DE35\n" passaria no teste; use re.fullmatch em Python e \z (ou o modificador D) em PHP. Em Java, String.matches já exige que a expressão case com o texto inteiro, e as âncoras são dispensáveis. Em C#, Regex.IsMatch procura em qualquer ponto, então mantenha ^ e $ e prefira \z no fim. Esses detalhes importam quando o valor vem de um arquivo ou formulário que pode trazer espaços e quebras de linha: o mais seguro é remover espaços das pontas antes do teste.

CPF ou CNPJ em uma regex

Para um campo “CPF ou CNPJ”, junte as duas expressões com alternância:

cpf-ou-cnpj.js
const CPF_OU_CNPJ = /^(?:\d{3}\.?\d{3}\.?\d{3}-?\d{2}|[A-Z0-9]{2}\.?[A-Z0-9]{3}\.?[A-Z0-9]{3}\/?[A-Z0-9]{4}-?\d{2})$/;

function tipoDocumento(valor) {
const v = String(valor).toUpperCase();
if (!CPF_OU_CNPJ.test(v)) return null;
return v.replace(/[^A-Z0-9]/g, '').length === 11 ? 'cpf' : 'cnpj';
}

tipoDocumento('529.982.247-25');     // 'cpf'
tipoDocumento('12.abc.345/01de-35'); // 'cnpj'
tipoDocumento('529.982.247-2');      // null

O grupo (?:...) garante que as âncoras se apliquem às duas alternativas. O CPF continua só numérico, então a primeira alternativa mantém \d. A distinção pelo tamanho é segura porque, depois de limpos, o CPF tem 11 caracteres e o CNPJ, 14. Repare que a limpeza usa [^A-Z0-9], e não \D: com \D, as letras do CNPJ seriam descartadas e o tamanho sairia errado. O guia de regex de CPF traz as expressões só de CPF.

Google Forms, planilhas e HTML pattern

Google Forms. Em Validação da resposta, escolha Expressão regular e Corresponde a. O Forms usa uma sintaxe no estilo RE2, sem lookahead, lookbehind nem retrovisores. Como o usuário pode digitar em minúsculas, aceite as duas caixas:

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

Escreva na mensagem de erro o formato esperado, por exemplo “Use o formato 12.ABC.345/01DE-35 ou 11.222.333/0001-81”.

Google Planilhas. REGEXMATCH usa o mesmo dialeto. Com a planilha em português, separe os argumentos com ponto e vírgula e converta para maiúsculas antes:

=REGEXMATCH(UPPER(TO_TEXT(A2)); "^[A-Z0-9]{2}\.?[A-Z0-9]{3}\.?[A-Z0-9]{3}/?[A-Z0-9]{4}-?[0-9]{2}$")

Formate a coluna como texto antes de colar os dados. Uma coluna numérica descarta zeros à esquerda e não comporta letras.

HTML pattern. O navegador ancora o padrão no início e no fim, e não há barras delimitadoras:

<label for="cnpj">CNPJ</label>
<input id="cnpj" name="cnpj" autocapitalize="characters" maxlength="18"
       pattern="[A-Za-z0-9]{2}\.?[A-Za-z0-9]{3}\.?[A-Za-z0-9]{3}/?[A-Za-z0-9]{4}-?[0-9]{2}"
       title="14 caracteres, com ou sem pontuação">

Os navegadores atuais compilam o pattern com a flag v, que é estrita com escapes: \. funciona, mas \- fora de colchetes faz o navegador ignorar o atributo. Por isso o hífen e a barra ficam sem escape. Não use inputmode="numeric": no celular, ele abre um teclado sem letras.

Máscara de input que aceita letras

As máscaras clássicas de CNPJ começam com replace(/\D/g, ''), que apaga as letras. A versão abaixo converte para maiúsculas, mantém letras e dígitos e insere a pontuação conforme o usuário digita:

mascara-cnpj.js
function mascaraCnpj(valor) {
const c = String(valor).toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 14);
return c.replace(
  /^([A-Z0-9]{2})([A-Z0-9]{1,3})?([A-Z0-9]{1,3})?([A-Z0-9]{1,4})?([A-Z0-9]{1,2})?$/,
  (_, a, b, d, e, f) => a + (b ? '.' + b : '') + (d ? '.' + d : '') + (e ? '/' + e : '') + (f ? '-' + f : ''),
);
}

mascaraCnpj('12abc3');             // '12.ABC.3'
mascaraCnpj('12abc34501d');        // '12.ABC.345/01D'
mascaraCnpj('12.abc.345/01de-35'); // '12.ABC.345/01DE-35'

Os grupos são gulosos, então cada um se completa antes de o próximo começar, e os opcionais só geram separador quando têm conteúdo. A máscara não impede uma letra nas duas últimas posições; essa checagem é da validação. Para cursor e colagem em React, Vue e Angular, veja o guia de máscara de CPF, cuja técnica é a mesma, e o formatador de CNPJ para o comportamento esperado.

Regex não substitui o dígito verificador

As expressões alfanuméricas com máscara ou flexíveis aceitam 12.ABC.345/01DE-36, que tem o formato certo e o segundo dígito errado. Regex lê caracteres; o dígito verificador exige uma soma ponderada e uma divisão por 11, com o valor de cada caractere dado pelo código ASCII menos 48. O fluxo completo é: conferir o formato, normalizar para 14 caracteres em maiúsculas e calcular os verificadores.

Em motores com lookahead e retrovisores (JavaScript, Python, Java, PHP), dá para recusar sequências repetidas na própria regex:

const SEM_REPETIDOS = /^(?!([A-Z0-9])\1{11})[A-Z0-9]{12}\d{2}$/;

Isso não funciona no Google Forms nem em outros ambientes RE2, e mesmo onde funciona, a checagem dos dígitos continua obrigatória. A função completa está em CNPJ em JavaScript e nas demais linguagens; o passo a passo do cálculo, no guia sobre a estrutura do CNPJ; e o validador de CNPJ confere qualquer número na hora.

Perguntas frequentes

Qual regex aceita o CNPJ alfanumérico com e sem pontuação?

Use ^[A-Z0-9]{2}\.?[A-Z0-9]{3}\.?[A-Z0-9]{3}\/?[A-Z0-9]{4}-?\d{2}$. As 12 primeiras posições aceitam letras e dígitos, os separadores são opcionais e os dois últimos caracteres são sempre dígitos.

A regex antiga de CNPJ ainda funciona?

Só para CNPJs numéricos. Expressões com \d nas 12 primeiras posições recusam números como 12.ABC.345/01DE-35, atribuídos a novas inscrições desde julho de 2026. Troque \d por [A-Z0-9] nessas posições.

Dá para validar o dígito verificador do CNPJ com regex?

Não. O dígito depende de uma soma ponderada e de uma divisão por 11, operações que regex não faz. Use regex para o formato e uma função para os dígitos.

Leia também