Normadata · Data Quality API

Normadata API vs. expressões regulares (regex)

Quando uma regex é suficiente para validar um identificador fiscal e quando você precisa de uma API?

TL;DR

A resposta honesta: às vezes a regex é suficiente. Se você só precisa validar um CPF em um projeto pessoal com uma verificação básica de comprimento, uma regex simples é perfeitamente razoável. Mas há cenários em que a regex vai falhar de formas silenciosas e custosas. Este guia explica a diferença com exemplos reais do contexto brasileiro.

Comparação rápida

AspectoRegex (artesanal)Normadata API
CustoGratuitoGratuito em beta; precificação pós-beta não anunciada
Verifica dígito verificador?Não (regex não consegue calcular módulo 11)Sim — algoritmo completo por país
Multi-país?Você precisa de uma regex por país (e mantê-la)Sim — um endpoint, cobertura multi-país
Normaliza o formato?NãoSim — retorna forma canônica
Detecta prefixos inválidos (ex. CNPJ)?Apenas se a regex contempla explicitamenteSim — regras de prefixo inclusas
Manutenção quando o padrão muda?Sua responsabilidadeResponsabilidade do Normadata
Funciona em qualquer linguagem?Sim (com variações de sintaxe)Sim — HTTP, qualquer stack
Latência?~0 ms (local)<50 ms (chamada de API)

Quando usar cada um?

Quando a regex é suficiente
  • Um único país, um único tipo de identificador, e o dígito verificador não é crítico para o seu caso de uso.
  • Protótipo ou MVP onde a prioridade é velocidade de desenvolvimento, não robustez.
  • O identificador não tem dígito verificador (ex. RG brasileiro, que não usa módulo 11 de forma padronizada nacionalmente).
  • Você já tem a biblioteca instalada e ela funciona corretamente no seu conjunto de testes.
  • Orçamento zero para dependências externas e o time consegue manter as regex.
Quando a API ganha
  • Multi-país: você tem usuários ou clientes no Brasil, Argentina, México, Colômbia — cada um com suas próprias regras de identificador.
  • O identificador tem dígito verificador complexo (CPF, CNPJ, CUIT, RFC, RUT): a regex detecta o formato mas não valida o checksum.
  • Você precisa de normalização: que '123.456.789-09' e '12345678909' sejam tratados como o mesmo CPF.
  • Stack multi-linguagem (Python, Go, JS, Java): uma única API em vez de uma regex por linguagem.
  • O time não quer manter 10-20 regex com seus casos extremos, encodings e atualizações.
  • Você vai rodar match ou dedupe sobre os identificadores e precisa da forma canônica como base — algo que uma regex não te dá, mas o match/dedupe você roda você mesmo.

O problema real: a regex que parece funcionar mas não valida

Considere este exemplo com CPF. A regex mais comum encontrada no Stack Overflow em PT: `^\d{3}\.\d{3}\.\d{3}-\d{2}$` ou simplesmente `^\d{11}$`. Parece correta — valida comprimento e caracteres. Mas o CPF 111.444.777-00 (onde os dígitos verificadores corretos são 3 e 5, não 0 e 0) passa essa regex sem problema. O número é estruturalmente inválido pelo algoritmo da Receita Federal, mas a regex não sabe disso. Isso significa que você pode armazenar milhares de CPFs inválidos no seu banco de dados, todos com formato aparentemente correto. Pior ainda: se depois você precisar fazer correspondência ou deduplicação contra dados de clientes, os CPFs mal validados vão gerar falsos negativos.

Código comparativo: Python, ambos os lados

O exemplo a seguir mostra como o mesmo CPF inválido (11144477700) passa a regex mas falha na API. A diferença está nos dígitos verificadores: os corretos para essa base são 3 e 5, não 0 e 0.

Exemplos de código

Regex: aceita um CPF com dígito verificador errado
import re

CPF_REGEX = re.compile(r'^\d{11}$')

def validate_with_regex(cpf: str) -> bool:
    digits = cpf.replace('.', '').replace('-', '').replace(' ', '')
    return bool(CPF_REGEX.match(digits))

print(validate_with_regex("111.444.777-35"))  # True  (valid)
print(validate_with_regex("111.444.777-00"))  # True  (WRONG — invalid check digit, should fail)
print(validate_with_regex("000.000.000-00"))  # True  (WRONG — known invalid CPF pattern)
Normadata API: detecta o dígito verificador errado no CPF
import httpx

def validate_cpfs(cpfs: list[str]) -> list[dict]:
    response = httpx.post(
        "https://api.normadata.io/v1/validate/tax-ids",
        headers={"X-API-Key": "nd_your_key"},
        json={"items": [
            {"id": str(i), "value": v, "country": "BR"}
            for i, v in enumerate(cpfs)
        ]},
    )
    return response.json()["results"]

# Same endpoint for 1 or N — up to 1000 per request
results = validate_cpfs(["111.444.777-35", "111.444.777-00"])

print(results[0]["valid"])  # True
print(results[1]["valid"])  # False — wrong check digit
print(results[1]["error"])  # "invalid check digit"
Limitações

O Normadata é uma API hospedada — requer chamada de rede, tem latência (embora baixa) e terá custo pós-beta. Se o seu caso de uso é de um único país, sem dígito verificador complexo, e você consegue manter o código, uma regex pode ser a ferramenta correta. O Normadata não é a resposta para tudo: é a resposta para multi-país, dígitos verificadores complexos (CPF, CNPJ, CUIT, RFC) e normalização.

Perguntas frequentes

Posso usar regex para o CPF?

Você pode validar o formato (11 dígitos, opcionalmente com pontos e traço), mas não pode validar os dois dígitos verificadores com uma regex. O algoritmo do CPF usa módulo 11 com duas rodadas de cálculo. Existem CPFs com formato correto mas dígito verificador incorreto — uma regex os aceitaria.

Quanto custa o Normadata após a beta?

A precificação pós-beta não está anunciada. Durante a beta privada, o acesso é gratuito. Se você quiser acesso antecipado e precificação preferencial, pode se inscrever na lista de espera.

A API funciona com qualquer linguagem?

Sim. É HTTP puro com JSON. Funciona com qualquer linguagem que consiga fazer um POST request: Python, JavaScript, Go, Ruby, Java, PHP, Rust, etc. Nenhum SDK proprietário é necessário.

E os casos extremos de regex multi-país?

São muitos e não intuitivos. O CNPJ tem 14 dígitos com dois dígitos verificadores calculados com pesos distintos — diferente do CPF. O RFC mexicano tem 12 caracteres para pessoas jurídicas e 13 para físicas, com regras de derivação de nome e data. O RUT chileno tem um dígito verificador que pode ser a letra K. Manter regex corretas e atualizadas para cada país é um compromisso de tempo que uma API resolve.