O uso de expressões regulares em JavaScript pode tornar bem compacta, flexível e poderosa a validação cliente (no navegador web) de campos de formulário, algo muito recomendado como pré-verificação do conteúdo de um formulário antes de submetê-lo ao servidor. O recurso de expressão regular surgiu no JavaScript 1.2, implementado desde a versão 4 de ambos os principais navegadores: Internet Explorer e Netscape Navigator (atual Mozilla).
Para cada tipo de conteúdo — numérico, data, endereço eletrônico etc. — podemos montar uma expressão regular apropriada para sua validação, de acordo com o formato e características desejadas. A validação do conteúdo de um campo através de uma expressão regular para o seu respectivo tipo consiste simplesmente em aplicar o padrão da expressão regular e testá-lo no texto desejado, com o método test( ).
Começamos com uma validação bem trivial: a validação de entrada de um número inteiro não-negativo sem sinal, ou seja, apenas dígitos.
Use o formulário de exemplo ao lado para validar um número apenas com dígitos (inteiro não-negativo sem sinal).
Em JavaScript, uma expressão regular é delimitada por uma barra
/
inicial e outra final. Cada expressão de validação sempre
começa com ^
(início de linha) e termina com
$
(fim de linha), para garantir que abrange o conteúdo
inteiro do texto (parâmetro) a ser validado.
Existe uma seqüência de expressão regular que significa um dígito (0 a 9):
\d
. Adicionando um +
após essa seqüência, significa
"uma ou mais ocorrências da seqüência precedente". Isto é, um ou mais dígitos.
Note que isso implica o preenchimento obrigatório; é melhor que o caso do campo
não preenchido (vazio) seja tratado à parte. Assim, temos a expressão
regular completa para validar um número apenas composto por dígitos:
reDigits = /^\d+$/;
Apresentamos agora um exemplo mais complexo de uso de expressão regular para a validação de números reais em ponto flutuante (decimal). As expressões definidas permitem, como opcionais: sinal, separadores de milhar e casas decimais. Não é tratada neste exemplo a notação científica (com expoente).
Use o formulário de exemplo ao lado para validar um número real decimal. Escolha pela caixa de seleção o idioma usado na expressão regular de validação, que define os carateres usados como separador de milhar e casas decimais.
As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir.
reDecimalPt = /^[+-]?((\d+|\d{1,3}(\.\d{3})+)(\,\d*)?|\,\d+)$/; reDecimalEn = /^[+-]?((\d+|\d{1,3}(\,\d{3})+)(\.\d*)?|\.\d+)$/;
Agora, vamos entender esse emaranhado de símbolos. Apresentarei a explicação para a expressão regular em Português. A lógica é idêntica para Inglês, trocando apenas os separadores de milhar e decimal (vírgula e ponto).
[+-]?
indica um caractere opcional (?
),
de sinal positivo ou negativo ([+-]
).(forma1|forma2)
representa a condição "ou" entre as duas formas.\,\d+
significa um número iniciado por vírugula (\,
)
seguido de um ou mais (+
) dígitos numéricos (\d
).
Isso significa que o número ,123
é aceito como
válido, ficando o zero da parte inteira subentendido (0,123).
Se esta forma não for desejada, basta retirar esta condição e deixar apenas
a 1ª forma, que obriga uma parte inteira.?
que denota opcionalidade: (\,\d*)?
.\d+
.\d{1,3}
— seguindo-se um ou mais (+
)
grupos de um ponto e 3 dígitos: (\.\d{3})+
.Note que a expressão foi montada de forma a não aceitar espaços antes ou depois do texto, nem entre o sinal e o número. Obviamente, isso e tudo o mais pode ser adaptado de acordo com a necessidade.
Finalizamos mostrando um caso específico bem comum da validação de números decimais: valores financeiros.
Use o formulário de exemplo ao lado para validar um valor financeiro.
O valor financeiro é uma simplificação do número decimal visto anteriormente, não permitindo sinal e exigindo sempre 2 casas decimais e separador de milhar obrigatório. Separadores de decimal e milhar estão no formato em português: vírgula e ponto, respectivamente. A expressão regular usada é a seguinte:
reMoeda = /^\d{1,3}(\.\d{3})*\,\d{2}$/;
Use o formulário de exemplo ao lado para validar uma data. Escolha pela caixa de seleção a complexidade da expressão regular usada na validação.
As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir. As expressões 4 e 5 estão exibidas em mais de uma linha apenas para melhor legibilidade, mas devem ser consideradas como em uma única linha cada.
reDate1 = /^\d{1,2}\/\d{1,2}\/\d{1,4}$/; reDate2 = /^[0-3]?\d\/[01]?\d\/(\d{2}|\d{4})$/; reDate3 = /^(0?[1-9]|[12]\d|3[01])\/(0?[1-9]|1[0-2])\/(19|20)?\d{2}$/; reDate4 = /^((0?[1-9]|[12]\d)\/(0?[1-9]|1[0-2])|30\/(0?[13-9]|1[0-2]) |31\/(0?[13578]|1[02]))\/(19|20)?\d{2}$/; reDate5 = /^((0[1-9]|[12]\d)\/(0[1-9]|1[0-2])|30\/(0[13-9]|1[0-2]) |31\/(0[13578]|1[02]))\/\d{4}$/;
Estas expressões regulares vão do mais simples ao mais completo, da seguinte forma:
[0-3]?\d
); o primeiro dígito do mês, se
houver, deve ser 0 ou 1 ([01]?\d
); passamos a aceitar apenas
2 ou 4 dígitos para o ano.(0?[1-9]|[12]\d|3[01])
) e meses 1 a 12
((0?[1-9]|1[0-2])
). E aqui optamos por forçar
os 2 primeiros dígitos do ano (correspondentes ao século),
quando fornecidos, a serem 19 ou 20 ((19|20)?\d{2}
).(0?[1-9]|[12]\d)
) são aceitos
em todos os meses (1 a 12): (0?[1-9]|1[0-2])
(0?[13-9]|1[0-2])
(0?[13578]|1[02])
.\d{4}
) como ano.A única coisa que a expressão mais completa (e complexa) não é capaz de testar é a validade do dia 29/fev apenas para anos bissextos.
A obrigatoriedade ou não de dois dígitos no dia e no mês
é facilmente controlada com a ausência ou não do operador de
opcionalidade ?
após o primeiro dígito.
As expressões apresentadas também ofereceram diversas
possibilidades para a validação dos dígitos do ano.
Use o formulário de exemplo ao lado para validar um horário ou tempo. Escolha pela caixa de seleção a complexidade da expressão regular usada na validação.
As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir. As possibilidades de variação para horário (hora/minutos/etc. de um dia) ou tempo (período de tempo decorrido, independente de dia) são ilimitadas. Exemplificamos aqui alguns casos típicos, que podem ser combinados e alterados conforme a necessidade.
reTime1 = /^\d{2}:\d{2}$/; reTime2 = /^([0-1]\d|2[0-3]):[0-5]\d$/; reTime3 = /^(0[1-9]|1[0-2]):[0-5]\d$/; reTime4 = /^\d+:[0-5]\d:[0-5]\d$/; reTime5 = /^\d+:[0-5]\d:[0-5]\.\d{3}\d$/;
Use o formulário de exemplo ao lado para validar um endereço de e-mail (correio eletrônico).
As expressões regulares utilizadas nesta validação estão apresentadas no quadro a seguir. As expressões estão exibidas em mais de uma linha apenas para melhor legibilidade, mas devem ser consideradas como em uma única linha cada.
reEmail1 = /^[\w!#$%&'*+\/=?^`{|}~-]+(\.[\w!#$%&'*+\/=?^`{|}~-]+)* @(([\w-]+\.)+[A-Za-z]{2,6}|\[\d{1,3}(\.\d{1,3}){3}\])$/; reEmail2 = /^[\w-]+(\.[\w-]+)*@(([\w-]{2,63}\.)+[A-Za-z]{2,6} |\[\d{1,3}(\.\d{1,3}){3}\])$/; reEmail3 = /^[\w-]+(\.[\w-]+)*@(([A-Za-z\d][A-Za-z\d-]{0,61}[A-Za-z\d]\.)+ [A-Za-z]{2,6}|\[\d{1,3}(\.\d{1,3}){3}\])$/;
A principal especificação para regras endereço de
correio eletrônico (e-mail) é o padrão Internet
RFC 2822:
Internet Message Format, seção 3.4.1 sobre
especificação de endereços. Basicamente, o endereço
segue a forma nome-local@domínio
, onde
nome-local especifica o usuário, e domínio especifica o
seu endereço ou servidor.
As regras de nome-local são definidas de forma muito ampla na
RFC 2822 e portanto são bastante dependentes de restrições
específicas adotadas por cada servidor de domínio e tecnologia
implementada. Pela especificação, um nome pode ser uma ou mais
"palavras atômicas" sem espaço, contendo caracteres dentre
letras (maiúsculas/minúsculas), dígitos (0-9) e os
símbolos ! # $ % & ' * + - / = ? ^ ` { | } ~
;
as palavras são separadas entre si por ponto (.
).
Um domínio pode ser especificado por nome ou por número IP.
O nome de domínio tem a sintaxe geral
subdomínio(s).nome-principal.TLD
.
Subdomínio(s), separados por ponto, são opcionais.
Os terminadores de domínio — conhecidos como domínio
primário, nível-raiz, nível-topo ou simplesmente pela
sigla TLD (Top-Level Domain) — são definidos pelo organismo
internacional Internet Assigned Number Authority
(IANA) e podem ser:
As regras de nome de domínio principal variam de país para país; a grande maioria aceita de 2 a 63 caracteres, que podem ser letras, algarismos ou o hífen (desde que este não seja nem o primeiro nem o último caractere), segundo a recomendação de sintaxe especificada nas RFC 1034 (3.5) e RFC 1035 (2.3.1). Não é considerada diferenciação entre letras maiúsculas e minúsculas. Navegadores Internet antigos podem ter problema em reconhecer nomes de domínio com mais de 26 caracteres; por isso, vários países (inclusive o Brasil) limitam nomes a este tamanho. Com algumas restrições, podem ser aceitos nomes com caracteres internacionais (acentuados, Unicode etc.).
Na especificação de um domínio no endereço de e-mail,
também pode ser aceito um número IP diretamente, entre colchetes,
na forma [n1.n2.n3.n4]
onde n1 a n4
são números entre 0 e 255.
As especificações e regras para endereços de correio eletrônico e nomes de domínio são amplas, imprecisas e cheias de situações específicas, de forma que uma expressão regular de validação pode ser desde muito flexível até bastante restritiva, conforme a necessidade.
Nos exemplos de expressão regular acima, temos:
[\w!#$%&'*+/=?^`{|}~-]
; e o domínio
tem definição bem livre, por nome basicamente fixando apenas
que o TLD deve ter entre 2 e 6 caracteres: [A-Za-z]{2,6}
;
ou por número IP entre colchetes: \[\d{1,3}(\.\d{1,3}){3}\]
.[\w-]+(\.[\w-]+)*
), onde cada palavra é definida por
[\w-]+
permitindo assim letra, dígito, sublinhado e
hífen. Também limita o tamanho de nomes de domínio
entre 2 e 63 caracteres apenas com letras, dígitos, sublinhado e
hífen: [\w-]{2,63}
.\w
para não permitir o sublinhado e
garante que não há hífen nem na primeira nem na
última posição, conforme RFC 1034/1035. O resultado
é o seguinte para representar um nome de domínio:
[A-Za-z\d][A-Za-z\d-]{0,61}[A-Za-z\d]
.Uma última dica: para os domínios como número IP,
foram usadas seqüências de 1 a 3 dígitos (\d{1,3}
)
para cada um dos 4 números componentes do IP. Para validar precisamente
cada número entre 0 e 255, o padrão de expressão regular
poderia ser ([01]?\d?\d|2[0-4]\d|25[0-5])
.
Fica como "exercício" para o leitor construir uma expressão que represente um
TLD apenas de duas letras (país), ou um dos TLDs genéricos ou de infra-estrutura
atualmente existentes.
Escolhida a expressão regular mais adequada para a validação de certo tipo de dado, criar uma função JavaScript de validação para esse tipo fica trivial assim:
function isTipo(pVal) { var reTipo = /^...$/; // Onde ... é a expressão regular apropriada return reTipo.test(pVal); }
Para entender e construir melhor expressões regulares adequadas a cada necessidade, sugiro as seguintes referências em português:
E estas em inglês:
É importante ressaltar que a validação de formulários que são submetidos ao servidor web jamais deve depender apenas de JavaScript no lado cliente, pois não se pode assegurar que o recurso esteja ativado e funcionando corretamente em todos os navegadores utilizados no acesso. Implementada ou não uma validação em JavaScript, deve sempre haver uma validação dos dados recebidos no servidor de aplicação. O uso de validação via JavaScript cliente serve essencialmente como um facilitador para pré-validação no lado cliente, possibilitando que o usuário tenha seus dados verificados ainda antes de submeter o formulário, evitando assim ter de aguardar o processamento pelo servidor para só então ser informado de que eventualmente errou algo e deve corrigir.
Expressão regular é um recurso também disponível em linguagens utilizadas em servidores de aplicação web, como Java, ASP.NET, PHP, Perl e outras, de forma que essa técnica pode ser usada analogamente para validação no lado servidor, observadas as diferenças de sintaxe e implementação de expressão regular em cada linguagem.
Além da validação de máscaras/formatos de texto como visto aqui, expressões regulares são também muito úteis na própria aplicação ou remoção de máscaras e formatação de texto. Veja um exemplo disto no artigo sobre Tratamento de CPF e CNPJ em JavaScript.
© 2003-2020, Márcio d'Ávila, mhavila.com.br, direitos reservados. O texto e código-fonte apresentados podem ser referenciados, distribuídos e utilizados, desde que expressamente citada esta fonte e o crédito do(s) autor(es). A informação aqui apresentada, apesar de todo o esforço para garantir sua precisão e correção, é oferecida "como está", sem quaisquer garantias explícitas ou implícitas decorrentes de sua utilização ou suas conseqüências diretas e indiretas.