Pular para o conteúdo
ValidadorCNPJ Gerar CNPJ

Padrões prontos

Regex de CNPJ alfanumérico

Expressões regulares corretas para o novo formato — com e sem máscara, por linguagem, e o que a regex não consegue validar.

As três regex que você precisa

Expressões regulares de CNPJ alfanumérico
UsoExpressão
Sem máscara (14 caracteres)^[0-9A-Z]{12}\d{2}$
Com máscara (18 caracteres)^[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}\/[0-9A-Z]{4}-\d{2}$
Aceitando as duas formas^[0-9A-Z]{2}\.?[0-9A-Z]{3}\.?[0-9A-Z]{3}\/?[0-9A-Z]{4}-?\d{2}$
Regex confere formato, não confere dígito verificador. 12.ABC.345/01DE-00 casa perfeitamente com todos os padrões acima e mesmo assim é inválido. Sempre combine a regex com o cálculo do módulo 11.

O que muda em relação à regex antiga

Comparação entre regex antiga e nova
Antes (só números)Agora (alfanumérico)Observação
^\d{14}$^[0-9A-Z]{12}\d{2}$as 12 primeiras posições ganham letras
^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$^[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}\/[0-9A-Z]{4}-\d{2}$a máscara não mudou, só o conjunto de caracteres
[0-9]{14} em busca livre\b[0-9A-Z]{12}[0-9]{2}\bpara extrair CNPJ de texto corrido

Por linguagem

javascript / typescript
const CNPJ_LIMPO = /^[0-9A-Z]{12}\d{2}$/;
const CNPJ_MASCARADO = /^[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}\/[0-9A-Z]{4}-\d{2}$/;
const CNPJ_QUALQUER = /^[0-9A-Z]{2}\.?[0-9A-Z]{3}\.?[0-9A-Z]{3}\/?[0-9A-Z]{4}-?\d{2}$/;

// Extrair CNPJs de um texto qualquer
const ENCONTRAR = /\b[0-9A-Z]{2}\.?[0-9A-Z]{3}\.?[0-9A-Z]{3}\/?[0-9A-Z]{4}-?\d{2}\b/g;

const texto = 'Contrato firmado com 12.ABC.345/01DE-35 e 11.222.333/0001-81.';
console.log(texto.toUpperCase().match(ENCONTRAR));
python (re)
import re

CNPJ_LIMPO = re.compile(r"^[0-9A-Z]{12}\d{2}$")
CNPJ_MASCARADO = re.compile(r"^[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}/[0-9A-Z]{4}-\d{2}$")

# Em Python, prefira fullmatch a match: match casa apenas o começo da string.
bool(CNPJ_LIMPO.fullmatch("12ABC34501DE35"))  # True
php (pcre)
$limpo = '/^[0-9A-Z]{12}\d{2}$/';
$mascarado = '#^[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}/[0-9A-Z]{4}-\d{2}$#';

// Use o delimitador # quando o padrão tiver barra, para não precisar escapar.
if (preg_match($limpo, strtoupper($valor))) {
    // formato ok — agora valide o dígito verificador
}
sql (postgresql, mysql, oracle)
-- PostgreSQL (operador ~)
SELECT * FROM empresa WHERE cnpj !~ '^[0-9A-Z]{12}[0-9]{2}$';

-- MySQL 8+
SELECT * FROM empresa WHERE cnpj NOT REGEXP '^[0-9A-Z]{12}[0-9]{2}$';

-- Oracle
SELECT * FROM empresa WHERE NOT REGEXP_LIKE(cnpj, '^[0-9A-Z]{12}[0-9]{2}$');

-- SQL Server não tem regex nativo; use LIKE com classes
SELECT * FROM empresa
WHERE LEN(cnpj) <> 14
   OR cnpj LIKE '%[^0-9A-Z]%'
   OR SUBSTRING(cnpj, 13, 2) LIKE '%[^0-9]%';
html — atributo pattern
<!-- O pattern do HTML já é ancorado: não use ^ nem $ -->
<input
  type="text"
  name="cnpj"
  inputmode="text"
  autocapitalize="characters"
  maxlength="18"
  placeholder="00.000.000/0000-00"
  pattern="[0-9A-Za-z]{2}\.?[0-9A-Za-z]{3}\.?[0-9A-Za-z]{3}/?[0-9A-Za-z]{4}-?[0-9]{2}"
  title="Informe um CNPJ com 14 caracteres, por exemplo 12.ABC.345/01DE-35"
  required>

Armadilhas comuns

Continue por aqui

Dúvidas sobre a regex

Qual a regex do CNPJ alfanumérico?

Sem máscara: ^[0-9A-Z]{12}\d{2}$. Com máscara: ^[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}\/[0-9A-Z]{4}-\d{2}$. Para aceitar as duas formas de uma vez, torne os separadores opcionais: ^[0-9A-Z]{2}\.?[0-9A-Z]{3}\.?[0-9A-Z]{3}\/?[0-9A-Z]{4}-?\d{2}$.

Regex valida o dígito verificador do CNPJ?

Não. Expressão regular reconhece formato, não faz aritmética. Ela barra tamanho errado e caracteres proibidos, mas 12.ABC.345/01DE-00 passa em qualquer regex. O dígito verificador exige o cálculo do módulo 11 — use a regex como primeiro filtro e o cálculo como validação real.

Devo aceitar letras minúsculas na regex?

Prefira normalizar a entrada com toUpperCase() antes de aplicar a regex. Se não puder, use [0-9A-Za-z] ou a flag de case-insensitive — mas lembre que o cálculo do dígito só funciona com maiúsculas.

Por que os dois últimos caracteres da regex são \d e não [0-9A-Z]?

Porque os dígitos verificadores continuam sendo numéricos por definição. Aceitar letras ali deixaria passar valores impossíveis, como 12ABC34501DEAB.