Regex para CEP, telefone e e-mail no Brasil
Uma expressão regular confere o formato de um valor, não se ele existe. Este guia traz expressões para CEP, telefone brasileiro com DDD (celular e fixo) e e-mail, explica cada parte e mostra as armadilhas de Python e PHP que deixam passar uma quebra de linha no fim ou dígitos de outros alfabetos.
Formato não é existência
Uma regex diz se 01310-100 tem cara de CEP, não se o CEP existe. Para existência, consulte uma base de CEPs, envie um SMS de confirmação ou um e-mail com link. Use a regex para barrar erros de digitação cedo, antes de ir ao servidor.
Para testar cada expressão com seus próprios exemplos, cole no testador de regex.
As expressões, parte por parte
CEP
^\d{5}-?\d{3}$: cinco dígitos, hífen opcional e três dígitos. Aceita 01310-100 e 01310100.
Telefone com DDD
\(?[1-9]{2}\)?: o DDD, com parênteses opcionais. Nenhum DDD brasileiro tem o dígito zero.9\d{4}: celular, com o 9 na frente e mais quatro dígitos antes do hífen.[2-5]\d{3}: telefone fixo, que começa de 2 a 5.-?\d{4}: hífen opcional e os quatro últimos dígitos.
Ela aceita (11) 91234-5678, 11912345678 e (11) 3123-4567. Com +55 na frente, remova o código do país antes de validar.
^[^\s@]+@[^\s@]+\.[^\s@]+$: algo, arroba, algo, ponto, algo, sem espaços. A especificação de e-mail permite formatos que quase ninguém usa, e regex maiores costumam recusar endereços válidos. Uma checagem simples mais um e-mail de confirmação é o caminho seguro.
Em JavaScript
No JavaScript, sem a flag m, o $ só combina no fim do texto, então as expressões funcionam como estão:
// CEP: 5 dígitos, hífen opcional e 3 dígitos
const reCEP = /^\d{5}-?\d{3}$/;
// Telefone com DDD: celular (9 + 8 dígitos) ou fixo (começa de 2 a 5)
const reTelefone = /^\(?[1-9]{2}\)? ?(?:9\d{4}|[2-5]\d{3})-?\d{4}$/;
// E-mail: só confere o formato geral. A prova real é enviar um e-mail de confirmação.
const reEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const cepValido = (v) => reCEP.test(v);
const telefoneValido = (v) => reTelefone.test(v);
const emailValido = (v) => reEmail.test(v); Em Python: fullmatch e re.ASCII
Duas armadilhas. Em Python, o $ também combina antes de uma quebra de linha no fim, então ^\d{8}$ aceita "01310100\n": use fullmatch. E o \d aceita dígitos de outros alfabetos, como os arábicos ٠١٣: use re.ASCII.
import re
# re.ASCII: sem ele, \d também aceita dígitos de outros alfabetos, como ٣
RE_CEP = re.compile(r"\d{5}-?\d{3}", re.ASCII)
RE_TELEFONE = re.compile(r"\(?[1-9]{2}\)? ?(?:9\d{4}|[2-5]\d{3})-?\d{4}", re.ASCII)
RE_EMAIL = re.compile(r"[^\s@]+@[^\s@]+\.[^\s@]+")
# fullmatch exige que o texto inteiro combine (o $ aceitaria uma quebra de linha no fim)
def cep_valido(v: str) -> bool:
return RE_CEP.fullmatch(v) is not None
def telefone_valido(v: str) -> bool:
return RE_TELEFONE.fullmatch(v) is not None
def email_valido(v: str) -> bool:
return RE_EMAIL.fullmatch(v) is not None Em PHP: o modificador D
No PHP, o $ tem o mesmo comportamento do Python. O modificador D no fim da expressão faz o $ exigir o fim real do texto:
<?php
// O modificador D faz o $ recusar uma quebra de linha no fim do texto
const RE_CEP = '/^\d{5}-?\d{3}$/D';
const RE_TELEFONE = '/^\(?[1-9]{2}\)? ?(?:9\d{4}|[2-5]\d{3})-?\d{4}$/D';
const RE_EMAIL = '/^[^\s@]+@[^\s@]+\.[^\s@]+$/D';
function cepValido(string $v): bool
{
return preg_match(RE_CEP, $v) === 1;
}
function telefoneValido(string $v): bool
{
return preg_match(RE_TELEFONE, $v) === 1;
}
function emailValido(string $v): bool
{
return preg_match(RE_EMAIL, $v) === 1;
} Cuidados
- Use sempre as âncoras
^e$(oufullmatch). Sem elas,abc01310-100xyzpassa, porque tem um CEP no meio. - Guarde telefone e CEP só com dígitos e aplique a máscara na exibição. Isso evita comparar
(11) 91234-5678com11912345678como valores diferentes. - Valide no servidor também. A validação no navegador ajuda quem digita, mas qualquer pessoa consegue enviar dados sem passar por ela.
- Para CPF e CNPJ, a regex não basta: o formato pode estar certo e o dígito verificador errado. Veja o guia de validação de CPF.
Achou um erro neste guia? Avise por e-mail.
Ferramentas para usar junto
Perguntas frequentes
Qual a regex para CEP?
Uma opção simples e segura é ^\d{5}-?\d{3}$, que aceita o CEP com e sem hífen. Em Python, use com fullmatch e re.ASCII. Em PHP, acrescente o modificador D.
Como validar celular brasileiro com regex?
O celular tem DDD de dois dígitos sem zero, o 9 na frente e mais oito dígitos. A expressão deste guia aceita o celular e o fixo, com ou sem parênteses, espaço e hífen.
Existe uma regex perfeita para e-mail?
Não na prática. A especificação permite formatos raros, e expressões muito grandes acabam recusando endereços válidos ou aceitando inválidos. Confira o formato geral e confirme com um e-mail.
Por que minha regex aceita um valor com quebra de linha no fim?
Em Python e PHP, o cifrão também combina antes de uma quebra de linha final. Use fullmatch no Python e o modificador D no PHP.