Você está na página 1de 89

O BÁSICO SOBRE EXPRESSÕES REGULARES

Desmistificando as Expressões Regulares.

por Diego Eis 15/06/2016 1 comentário ~ 5 min. / 997 palavras

Expressão Regular é uma das ferramentas mais úteis que você pode ter. Vira e mexe as Expressões Regulares (RegExp) resolvem
desde problemas de Find & Replace no editor até validação de dados em diversos níveis do seu projeto. Mas geralmente a gente só lê
sobre Expressões Regulares quando precisamos decifrar aquela linha maluca e ainda assim de um jeito meio descuidado, tateando e
tentando fazer dar certo uma combinação de caracteres sem sentido.

Entendendo as Expressões

Uma Expressão Regular é uma representação para que você encontre padrões em um texto. Esse texto pode ser qualquer coisa, desde o
valor de um campo de formulário ou simplesmente um search no seu editor de código predileto… Não importa… O objetivo é filtrar
padrões em um punhado de informação textual.

Se você entender que uma Expressão Regular é apenas uma representação formada por símbolos, você não vai ter dificuldades. Cada
símbolo representa um tipo de informação. Por exemplo: o . (ponto) é um curinga. Ele significa que você pode selecionar qualquer
caractere, ou seja, qualquer letra, caractere especial ou número. Exceto a quebra de linha, que é representado pelo símbolo \n.

Classe de caracteres

Vamos começar pelo mais fácil: quando você faz uma busca, você pode buscar uma combinação de caracteres específica, por exemplo:
no seu editor de código, se você fizer uma busca por a, ele vai te mostrar todas as letras a do documento. Mas e se você quiser procurar
todas as letras a e as letras e? Simples, você faz um agrupamento utilizando os colchetes []. Essa expressão irá encontrar todos os
caracteres que estiverem dentro dos colchetes. Veja esse exemplo, onde ele filtra as letras [ue]. Isso se chama classe de caracteres,
onde você encontra vários caracteres diferentes ao mesmo tempo.
Bom, se você quiser selecionar TODAS as letras do texto, você não precisa escrever o alfabeto inteiro dentro dos colchetes, basta só
usar a representação [A-z]. Isso quer dizer que ele pega as letras de A até Z, maiúsculas ou minúsculas.

Se você quiser pegar os números, por exemplo, use [0-9]. Se quiser todas as letras e todos números: [A-z0-9]. Pra facilitar a
expressão, você pode usar \w, que vai dar no mesmo.

Para você fazer uma negação da Classe criada, basta adicionar um ^ dentro da classe. Por exemplo, você quer pegar todas as
combinações que não sejam formadas pela sequência es: [^es]. Veja esse exemplo aqui.

Exemplos de classes de caracteres:

 A expressão [a-z] reconhece todas as letras minúsculas.


 A expressão [A-Z] reconhece todas as letras maiúsculas.
 A expressão [A-z] reconhece todas as letras maiúsculas e minúsculas.
 A expressão [A-Z0-9] reconhece todas as letras maiúsculas e números.
 A expressão [a-e] reconhece as letras a, b, c, d e e.

Atalhos para as classes mais comuns:

 A classe \w recupera todos os caracteres alpha numericos, ou seja, letras e números, mas não acentos ou caracteres especiais. É o
equivalente a [a-zA-Z_0-9]
 A classe \W pega TODOS os caracteres que não seja alpha numericos, ou seja, pontuações e espaços.
 A classe \s é o equivalente [ \t\n\x0B\f\r]
 A classe \d é o equivalente [0-9]

E as classses de negação. Lembrando que basta colocar o sinal de ^ logo depois do colchete inicial [:

 A expressão de classe [^y] reconhece qualquer caractere, exceto y.


 A expressão de classe [^a-e] reconhece qualquer caractere, exceto a, b, c, d e e.
 A expressão de classe [^\d] reconhece qualquer caractere, exceto 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9.

Múltiplos padrões
Imagine agora que você queira encontrar dois padrões diferentes de caracteres, por exemplo, duas palavras. Bastando usar o símbolo |
(pipe), que vai significar OU. Nesse caso a expressão irá reconhecer um ou o outro padrão. Veja esse exemplo onde recuperamos o
retorno das palavras dolor ou labore.

Âncoras

As âncoras recuperam a posição entre os caracteres, mas não os caracteres em si. Por exemplo, a expressão ^dolor, vai recuperar as
palavras dolor que estiverem no início da linha (veja o exemplo). A expressão dolor$ vai recuperar o termo que estiver no final da
linha (veja o exemplo).

Modos

Agora, suponha que você queira pegar uma sequência que contenha um termo parecido, mas que possa estar com algumas letras
maiúsculas ou minúsculas. Por exemplo os termos Lorem, lorem, loRem, lOrEm etc, bastaria usar a representação (?i) antes do
termo a ser buscada. A expressão ficaria assim (?i)lorem. Veja este exemplo aqui.

Brincando de validar um email

Uma tarefa muito corriqueira é a validação de campos de e-mail. Sem entrar nas polêmicas (validar essas coisas sempre é chato), mas é
legal para treinar o que você acabou de ler. A expressão para fazer a validação é essa:

^\w*(\.\w*)?@\w*\.[a-z]+(\.[a-z]+)?$

Explicando:

 A expressão ^ indica o começo da string/linha.


 \w* pega qualquer caracteres alpha numericos, é o equivalente a [a-zA-Z0-9_]. O asterísco é quantitativo, detectando qualquer
quantidade desses caracteres, iniciando no 0 e indo até o infinito.
 A expressão (\.\w*)? significa: parenteses inicia um agrupamento. A expressão \. detecta literamente um ponto .. A expressão \w*
qualquer quantidade de caracteres alpha numéricos.
 O ponto de interrogação (?) é quantitativo: determina que o que vier imediatamente antes dele aparecer na expressão 0 ou 1 vez. Nessa
expressão ele aparece duas vezes.
 O arroba seria o arroba do email mesmo…
 \w* que aparece depois do arroba já falamos várias vezes logo acima.
 \.[a-z] pega um ponto seguido de letras minúsculas. vai detectar algo como .com, .net, etc…
 + significa que o que estiver imediatamente antes dele precisa aparecer 1 ou mais vezes no termo.
 (\.[a-z]+): abrimos novamente um agrupamento com o parenteses. \. pega o ponto. A classe [a-z] seleciona qualquer letra
minúscula. E o mais aparece novamente, dizendo que tudo aquilo que estiver antes dele deve aparecer pelo menos 1 vez
 E a expressão $ pra finalizar significa final da string.

Veja funcionando abaixo:

Para você testar e aprender

Existem alguns sites pra facilitar a criação e o debug das expressões regulares, veja abaixo:

 https://regex101.com/r/vS7vZ3/224#javascript
 https://rubular.com
 https://aprenda.vidageek.net/aprenda/regex
 https://turing.com.br/material/regex/introducao.html#
 https://msdn.microsoft.com/pt-br/library/az24scfc(v=vs.110).aspx

Leia mais aqui no Tableless:


 Proteja seu código usando o Webpack
 Invertendo o Redux
 Trabalhando com serviços no Javascript
 Yarn: A evolução do NPM
 Conversão de tipos em JavaScript
https://medium.com/trainingcenter/entendendo-de-uma-vez-por-todas-expressões-regulares-parte-1-introdução-dfe63e289dc3
https://medium.com/trainingcenter/entendendo-de-uma-vez-por-todas-expressões-regulares-3538d42870f3
https://medium.com/trainingcenter/expressoes-regulares-parte-3-8fbd6b20a5f6
https://medium.com/trainingcenter/expressoes-regulares-parte-4-92c41516e80c
https://medium.com/trainingcenter/entendendo-de-uma-vez-por-todas-expressões-regulares-parte-5-5ffd39138f2
https://medium.com/trainingcenter/expressoes-regulares-parte-6-85804a357767
https://medium.com/trainingcenter/entendendo-de-uma-vez-por-todas-expressões-regulares-parte-7-66be1ac1f72d

ENTENDENDO DE UMA VEZ POR TODAS EXPRESSÕES REGULARES:


PARTE 1 — INTRODUÇÃO

Expressões Regulares

Apresentação

Fala pessoal, tudo certo? Meu nome é Raul, tenho 24 anos e sou desenvolvedor há quase 3 anos. Comecei a
programar na faculdade com Java, PHP, até me deparar com o fascinante mundo do client-side e resolver
abandonar um pouco o server-side pra entender a mágica da força trindade HTML, CSS e Javascript.
Há pouco mais de uma semana eu me deparei com um problema que todo desenvolvedor já se deparou — e
se ainda não, eu garanto que vai — que é encontrar um padrão textual em uma massa de dados. No caso, era
pra fazer uma leitura de um código HTML inteiro e filtrar determinadas informações. Essa prática é
chamada de Web Scraping.

Fazer isso manualmente apesar de trabalhoso, é fácil, afinal, é da natureza do ser humano buscar padrões
em todo lugar. Mas e programaticamente? Bom, aí as coisas começam a ficar um tanto complicadas, afinal,
são muitas variáveis como: “pode ou não vir uma classe”, “pode ou não ter id” e etc. É aí que a gente se
depara com as tão temidas Expressões Regulares.

Voltando ao meu problema, tentei fazer de diversas formas (mesmo sem saber direito o que eu estava
fazendo).

Tentando montar uma regex sem saber nada de regex!

Então eu decidi que eu iria estudar pra valer e aprender de uma vez por todas isso. E como é como dizem:

A melhor forma de aprender, é ensinando!


Escopo

Vou dividir essa série de artigos da seguinte maneira:

1. Introdução (esse)
2. Metacharacters
3. Classes de caracteres
4. Quantifiers
5. Capturando Grupos
6. Âncoras
7. Regex no mundo JavaScript

Espero que vocês gostem da série e passem a utilizar no dia-a-dia de vocês sem precisar consultar no Stack
Overflow! :p

Mas afinal, o que é Expressão Regular?

Expressão Regular é uma linguagem de busca de padrões. Resumindo bem a opera, é uma linguagem onde
dizemos o padrão (pattern) do texto que queremos encontrar, passamos o texto alvo (target) e pedimos para
uma Regex engine (motor) fazer essa busca. É como se fosse o famoso ctrl+f, só que muito mais profundo
e detalhado.
Fluxo de expressão regular.

Como mencionado, para que seja possível realizar uma busca utilizando Regex, é necessário uma Engine,
ou seja, um motor que tem a finalidade de avaliar o contexto e fazer a busca.

Cada linguagem de programação tem o seu motor e apesar de Regex ter um padrão fixo, há algumas
diferenças e detalhes na implementação em cada uma. Mas o que vai mudar de fato é a forma com que se
trabalha, e não a lógica e os padrões em si.

Show me the example

Bom, vamos ver como funciona esse tal de Regex na prática pra ficar mais fácil.
Digamos que eu tenho um arquivo CSV com milhares de linhas com informações de pessoas, contendo na
sequência: Nome; Endereço; Cep e Telefone.

João da Silva;Rua Cabloco terceiro, 25;11111-111;(99)9999-9999


Márcio Cunha;Rua João Gourlat, 150;12123111;(99)8888-9999

Então, queremos pegar apenas o CEP de todas as linhas de nosso arquivo. A forma mais fácil (não a mais
otimizada) de fazer isso seria:

\d\d\d\d\d-\d\d\d

Mas o que?

Calma jovem, muita calma. Vamos passo-a-passo:

O \d é uma classe de carácter (explicarei no próximo artigo), onde ele vale números de zero a nove (0–9).
Logo, sabemos que todo CEP possui 5 números, um hífen (-) e mais 3 números. Logo, temos:

1. \d\d\d\d\d (5 primeiros números)


2. - (hífen da máscara do CEP)
3. \d\d\d (3 últimos números)
Porém, perceba que no exemplo, o cep do Márcio não possui máscara, e mesmo assim iremos considerar
esse caso. Como podemos fazer isso?

No mundo da Regex, o ponto de interrogação tem vários super poderes e veremos todos eles durante a série.
Mas, um deles é o papel de quantifier, ou seja, ele é um atalho (short hand) que diz que um elemento pode
ou não aparecer na expressão.

Logo, para considerarmos o caso onde o hífen pode ou não vir, mudamos a nossa expressão para:

\d\d\d\d\d-?\d\d\d
Capturando CEP com e sem hífen!

Perceba que agora ambos os casos foram considerados.

Conclusão

Como eu comentei anteriormente, esse é apenas um exemplo bem rústico e simples do uso de expressões
regulares. Elas podem ficar muito mais elegante e fácil de ler e também muito mais complexas.

Caso queira testar você mesmo, pode utilizar o Regex101, um site que possui diferentes Regex Engine e até
gera o código para a linguagem, dado o target e o pattern.

Até o próximo artigo! =D


Entendendo de uma vez por todas Expressões Regulares:
Parte 2 — Metacharacters

Cozinhando meta… caracteres! (ba dum tss)

C ontinuando a saga mágica das Expressões Regulares, hoje vamos entender um pouco mais do que se
treta meta-caracteres no mundo da Regex! Mas antes, se você ainda não viu a parte um, clica nesse link e da
uma conferida!

Então, pega teu café/chá/chimarrão, respira e vem comigo!

Metacharacter
Metacharacter ou Meta-caractere é todo caractere que não possui o seu valor semântico propriamente dito,
ou seja, visualmente ele parece uma coisa, mas no fim ele tem um significado especial! — Hãm?

Quando você vê o caractere ponto (.) em um texto, qual é o significado dele? Bom, num texto normal
provavelmente ele tem o valor de ponto final, não é? Na mosca, jovem! Entretanto, esse é o valor semântico
associado ao português. No mundo das expressões regulares a história é um pouco diferente. Vamos dar
uma olhada na prática para elucidar melhor.

O texto abaixo possui 3 pontos (.):

Seja bem-vindo(a). Esse é o encantado mundo da Regex. Meu nome é Raul e


eu serei seu guia.

Sabendo que se quisermos selecionar um caractere específico em Regex, podemos passar ele diretamente na
expressão. Logo, vamos tentar fazer isso com o ponto:
90 matches

90 MATCHES?

Pois é. Em uma Expressão Regular, um ponto (.) tem o valor de qualquer caractere, ou seja, o que ele diz
pra engine é: “Pega mim TUDO que estiver no target”.

Mas Raul, eu quero selecionar o ponto, comofas?


Para tal, precisamos “escapar” o caractere utilizando a barra invertida (\). Com ela, falamos pra engine:
“Senhora Engine, por obséquio, pegue o valor literal deste caractere. O seu significado semântico.” e
pedindo com tanto polidez, nossa solicitação será atendida:

Agora sim, em?

Empolgante!

Há mais alguns caracteres que possuem esse mesmo comportamento, a maior parte deles são quantifiers, e
isso a gente vai ver futuramente.
Outros tipos de meta

Além do metacharacter citado, ainda temos um outro tipo. Esse é o inverso do anterior, ou seja, é quando o
caractere tem seu valor literal interpretado normalmente pela Engine, mas quando colocamos uma barra
invertida (\), concedemos super poderes à eles.

Números

Lembra do exemplo do artigo 1, onde usamos \d ? Então, ele é um exemplo muito fácil disso. Somente o d ,
é interpretado como a letra d. Mas usando a barra invertida, transformamos ele num “pegador de caracteres
alfanuméricos”, veja no exemplo a seguir:

Olha eu sem boné! \o


Olha eu com boné! \ô

Desse tipo, temos uma série que será extremamente útil, vamos dar uma olhada com mais calma em cada
um deles.

Espaços em Branco

Lembro uma vez onde na empresa que eu trabalhava, a gente teve um problema com uma integração de um
arquivo. Depois de muito quebrar cabeça, conseguiram descobrir que o software do cliente estava inserindo
um caractere em branco que, segundo a tabela UNICODE, era um outro tipo de espaço em branco. E pelo
fato de vir no meio do texto, um método trim() não resolvia.
No caso em questão, o pessoal não usou Regex, foram bem cangaceiros e conseguiram encontrar na raça!
Mas, talvez tivesse sido um pouco mais fácil utilizando Regex, não?

Para esses casos, temos um metacharacter especial que é o \s ! O que ele faz é considerar qualquer espaço
em branco, seja ele um espaço, um tab, uma nova linha, um form feed, e até mesmo um vertical tab (nem
sabia que existia tanto caractere para espaçamento).

Hands on!

nesse texto temos espaços, tabs,


e new line

Poderíamos tentar pegar um por um, mas vamos ser espertos e pegar todos sem erro:
Pegando todos os white spaces!

Então fica a regra: “Precisa considerar espaços em branco na sua expressão? \s”.

Word Characters

Word Chacaraters, ou caracteres de palavras (tradução livre), é o cara que vai nos ajudar a pegar todas as
letras, números e underscore (underline).

Uma coisa que precisa ser mencionada e ser gravada no âmago da memória de vocês desde já é:

Expressões Regulares são case sensitive!

Acredito que quem está lendo sobre expressões regulares já sabe o que é esse termo, mas caso você ainda
tenha algum tipo de dúvida, case sensitive é quando caracteres maiúsculos e minúsculos não possuem o
mesmo valor, ou seja, A é diferente de a, igual em senhas, sabe?

Quando queremos validar se um caractere é uma letra, podemos usar classes de caracteres (veremos no
próximo artigo), passando a seguinte expressão:
[A-Za-z]

No exemplo acima, falamos que esperamos uma letra que esteja dentro do alfabeto e pode ser maiúscula ou
minúscula. Mas vamos dizer que queremos pegar um nickname, e nele pode vir além de letras, números e
underline (_)?

[A-Za-z0-9_]

Poxa, olha o tamanho disso.

E é aqui que entra o \w ! A declaração acima, pode ser resumida apenas com \w. Duvida?

Expressão gigantesca
word character \w

Negando o meta-caractere

Legal esse monte de atalho pra gente usar, diz aí? Mas assim como eu me perguntei quando aprendi isso,
você também pode ter se perguntado:

Mas e se… eu quiser pegar qualquer caractere que NÃO for um número ou world character ou white space?

Para nossa alegria, existe uma forma bem simples de fazer essa negação. Nas linguagens de programação,
geralmente quando a gente quer negar uma condição booleana (true/false), apenas passamos uma
exclamação:
senhaRecebida == senha // A senha recebida é igual a senha?
senhaRecebida != senha // A senha recebida é diferente da senha?

Para fazermos isso, com esses 3 meta-caracteres que vimos, basta colocar a letra maiúscula! Sim, simples
assim!

Pega tudo o que NÃO FOR letra, número e underline.

Isso também funciona com \s :


Pega tudo o que NÃO FOR white space.
Importante

Essa lógica vai ser aplicada pra outros meta-caracteres que veremos mais a frente. Logo, lembre-se dela! :D

Conclusão

Esse artigo foi bem teórico apesar dos exemplos, mas é extremamente importante que você compreenda o
que são os meta-caracteres e como eles são entendidos, pois, nos tópicos seguintes eles serão
constantemente utilizados.
Espero que tenham gostado! Até o próximo! =D

Entendendo de uma vez por todas Expressões Regulares:


Parte 3 — Classes de Caractere

Regex

Fala galera, belezinha? Hoje o nosso bate-papo vai ser sobre uma das principais (e mais útil)
funcionalidades das expressões regulares, classes de caracteres.

Espero que estejam gostando da série e caso você seja novo por aqui, da uma olhada na parte 1, clicando
aqui.

Sem delongas, liga teu Pomodoro, pega teu café/chá/chimarrão, me dê a mão (me abraça) e vem comigo!

Classes de caracteres: O que são?


Classe de caractere é uma maneira de dizer à Regex Engine que queremos pegar um conjunto específico de
caracteres. Basicamente, é como se definíssemos que o que pode ou não aparecer naquele trecho (ou em
toda) da expressão. Vamos a um exemplo pra facilitar o entendimento.

Suponhamos que queremos analisar (de uma forma pouco grosseira) se uma data é valida ou não. Sabemos
que no formato PT_BR, ela segue o padrão dia/mês/ano (28/05/2017).

Esse padrão segue algumas regras básicas, por exemplo, o dia só pode começar com zero (0), um(1), dois(2)
ou três(3). Então, como podemos fazemos então para dizer à Regex que o primeiro número precisa ser um
desses 4 dígitos? Se você respondeu com classes de caracteres, parabéns! :D

Expressando uma classe (ou conjunto)

Uma classe de caracteres é expressada de duas maneiras, são elas:

Colchetes

O símbolo de colchetes ([]) são usados para indicar quais os caracteres queremos considerar. Voltando no
exemplo anterior, para expressar que queremos apenas os números 0, 1, 2 e 3, podemos fazer:
[0123]
Hífen mágico

Outra forma de escrever a mesma coisa do exemplo acima, de forma bem bacanuda e mais sucinta, é
utilizando o hífen (-).

Com ele, definimos um um range (alcance), ou seja, um valor inicial e um valor final, que no caso serve
para letras e números. Melhorando a expressão anterior, temos:

[0-3]

Temos o mesmo resultado, de uma forma bem mais elegante.

Ponto de atenção!

Quando comecei a estudar sobre Regex, me deparei com uma observação sobre o uso hífen dentro de
classes que me intrigou bastante.

Fora da classe o hífen é avaliado como hífen mesmo (valor semântico), mas como dito anteriormente,
dentro ele é avaliado como um range. Assim, suponhamos que você queira considerar um hífen, ou ponto-
e-virgula, ou exclamação em um trecho de texto. Para tal, podemos utilizar classe de caractere:
Character range is out of order!

Pois é! Tomamos um erro logo de cara. Mas por que isso?

Bem, o que a engine faz é tentar encontrar o range entre o ponto-e-virgula (;) e a exclamação (!). E como
isso não faz sentido, o erro acontece.

Mas e aí? Como fugir disso?

Lembra do post passado sobre meta-caracteres? Sim, o hífen é um deles! E para resolver o caso, precisamos
apenas passar a nossa amiga barra invertida (\):
Pegando o hífen!

Shorthand

A segunda maneira de filtrar uma classe de caracteres é utilizando uma forma abreviada (shorthand) da
própria linguagem.

Números

Em muitos casos, desejamos pegar números de zero (0) a nove (9). Logo, podemos fazer utilizando o hífen:
Utilizando hífen

Mas podemos simplificar ainda mais utilizando o shorthand \d que tem exatamente o mesmo significado
(números de 0 a 9):

Utilizando shorthand
Letras e números

No caso das letras, podemos definir na classe que queremos de aaté z maiúsculo ou minúsculo e números de
0a 9 , assim, usando hífen ficaria:

Classe, hífen, números e letras

O shorthand para esse mesmo valor seria o \w , mas com uma ressalva: ele considera underscore (_)
também:
Shorthand para números e letras
Qualquer caractere

Uma classe MUITO útil é o ponto ( . ). O ponto representa QUALQUER caractere, e quando eu digo
qualquer, é realmente qualquer (espaço, números, letras, etc.)

HANDS ON!

Bora codar!
Licença didática: Antes de mais nada, gostaria de deixar claro que a validação que faremos a seguir é bem
grosseira, ou seja, ela deixará brechas para uma data inválida, como 20/19/2999 (mês 19???). Assim, não
validem se ela é uma data válida (de acordo com o calendário) dessa maneira. =)

Com todo esse conceito novo em mente, vamos atacar as datas então.

Eu não sei vocês, mas eu particularmente quando vejo uma expressão regular, fico meio confuso. Então, pra
entender melhor, eu vou imaginando ela por blocos e no fim, junto todas as partes para entender o que ela
faz em si.

Para resolver não é diferente! Vamos atacar a data por blocos.

Dia

Para validar o dia, vamos seguir algumas regras:

 Pode vir unidade (9) ou dezena (09);


 Caso seja dezena, o primeiro número tem que ser entre 0 e 3;

// Lembrando, o ? tem valor de: pode ou não aparecer (veremos


futuramente mais afundo)
[0-3]?

 O segundo dígito pode ser de 0 a 9.


[0-3]?\d

 Para finalizar, vem uma barra ao final dessa expressão. A barra é um meta-caractere, logo,
precisamos escapar usando barra invertida:

[0-3]?\d\/

Assim, temos o resultado:

Dia: done!
Mês

Para validar o mês, seguimos as diretrizes:


 O primeiro digito só pode ser zero (0) ou um (1) e pode ou não aparecer:
[0-1]?

 O segundo digito pode ser qualquer número

[0-1]?\d

 Terminando ele, segue uma barra:

[0-1]?\d\/

Agora, juntando a expressão do dia e a expressão do mês, temos:

Dia e mês: done!


Ano

O ano, seguirá as seguintes diretrizes:

 Queremos que o seja seja 1000 e 2000, logo, o primeiro digito será entre 1 e 2:

// Note que não precisamos de range


[12]

 Os outros 3 digitos, pode ser de zero (0) a nove (9).

[12]\d\d\d

Agora juntando a expressão do dia, mês e ano, teremos:

Pattern de data: FOUND! :D


Apenas a titulo de curiosidade, podemos melhorar o ano utilizando um quantifier (veremos no próximo
artigo), que diz quantas vezes aquela pequena expressão pode aparecer, ficando:

// A classe \d tem que aparecer aparecer 3 vezes


[12]\d{3}

Mesmo resultado!

Extra: caracteres especiais

Antes de fechar o assunto, queria comentar um pouco a respeito sobre as letras e os caracteres especiais.
Lembra quando eu disse que a classe \w pega letras? Vamos tentar selecionar todas as letras da palavra
maçã:

Pois é, tanto o \w quanto o a-zA-Z levam em consideração apenas o alfabeto, ou seja, a até z. Como a língua
portuguesa é uma (p…) lindeza, e temos diversos símbolos como til (~), cedilha (ç) e etc, sempre que
quisermos validar textos que contenham esse tipo de informação, precisamos explicita-los dentro de uma
classe:
Considerando caracteres especiais

Assim, pense nessa possibilidade quando estiver montando suas expressões! :)

Conclusão

Classe de caracteres será sem dúvida, uma das coisas que você mais vai utilizar no uso das expressões
regulares. Portanto, vale um ponto de atenção e dedicação para entender de verdade como elas funcionam!

Espero que tenham gostado! Caso tenham alguma dúvida ou sugestão, podem me mandar mensagem que eu
terei o prazer de responder! \o
Entendendo de uma vez por todas Expressões Regulares: Parte 4— Quantifiers

“My precisous!” — Gollum

F ala galere, tudo em cima? Hoje é dia de mais um artigo sobre expressões regulares e hoje iremos
abordar os quantifiers (quantificadores), ou seja, formas de definir quantas vezes queremos que elementos
apareçam ou não em nossas expressões.

Lembrando: caso você seja novo por aqui, acesse o primeiro post.

Então simbora que a gente ta na metade já =D

Raul?… Raul…? …. Ahhh vamo nessa!


Quantifiers: O que são?

Como dito no começo do artigo, quantifier é uma forma de você dizer à Regex engine quantas vezes você
quer que aquele caractere apareça. No primeiro exemplo do primeiro post (link aqui) eu citei um caso onde
era necessário validar um CEP:

//Target
João da Silva;Rua Cabloco terceiro, 25;11111-111;(99)9999-9999
Márcio Cunha;Rua João Gourlat, 150;12123111;(99)8888-9999

Lembrando que as regras para a máscara do CEP são:

 5 dígitos iniciais;
 Um hífen (que pode não vir);
 3 dígitos finais.

Assim, resolvemos com a seguinte expressão:

\d\d\d\d\d-?\d\d\d

Resultando em:
aeHOOo

Porém, dessa maneira é um pouco estranha né? Repetimos a mesma condição (\d ) 5 vezes, depois mais 3
vezes. Mas, como deixar isso um pouco mais bonito? Sim, quantifiers.

Declarações

Existem algumas maneiras de declarar um quantifier, cada um, atendendo a um propósito em específico.
Nas maneiras a seguir, sempre que você ler “n” ou “m”, entenda como números inteiros quaisquer
(matemática feelings?).
Apareça “n” vezes
Quando queremos que um determinado caractere apareça especificamente “n” vezes, passamos o número
de vezes (n) entre chaves, após alguma declaração. Lembra do caso do CEP? Como sabemos exatamente
quantas vezes cada número deve aparecer, podemos mudar a nossa expressão de:

\d\d\d\d\d-?\d\d\d

Para

\d{5}-?\d{3}

E obtemos o mesmo resultado


refatorando regex com quantifier {n}

Apareça no mínimo “n” vezes


Há ainda os casos onde queremos que apareça um caracteres no mínimo “n” vezes. Para este caso,
declaramos novamente as chaves, o número mínimo de vezes e em seguida, uma virgula, ficando:

{n,}

Agora para ver na prática, vamos imaginar que queremos avaliar um texto onde deverá vir no mínimo 4
letras seguido de no mínimo 8 dígitos:

//Target
regex1234567
reg12345678
regex12345678
regex123456789012

Como sempre digo, resolver a expressão por partes, teremos para a primeira parte (mínimo 4 letras
[considerando maiúscula e minúscula]) a seguinte expressão:
[A-Za-z]{4,}

Para a segunda parte (no mínimo 8 dígitos), teremos:

\d{8,}

Juntando as duas partes e aplicando em nosso target, temos o resultado:

Resultado da expressão.

Perceba a primeira linha, não possuímos no mínimo 8 dígitos, logo, ela é desconsiderada. Na segunda linha,
temos os 8 dígitos mas não temos no mínimo 4 caracteres! Já na terceira e quarta linha, temos a nossa
condição totalmente atendida, uma vez que é no mínimo, ou seja, “n” ou mais!
Apareça no mínimo “n” e no máximo “m”
Mas e nos casos onde queremos definir o mínimo e o máximo? Bom, para esses, ainda utilizaremos chaves,
mas passaremos o número mínimo “n”, uma virgula, e o número máximo “m”:

{n,m}

Vamos imaginar que queremos validar um username com as seguintes regras:

1. Deve conter apenas letras minúsculas;


2. Pode conter números, underline e hífen;
3. Deve ter entre 3 e 16 caracteres.

Assim, teríamos a seguinte expressão:

^[a-z0-9_-]{3,16}$

Obs.: Não se preocupe com o ^ e o $ , são âncoras e veremos nos posts a seguir. Apenas tenha em mente
que eles delimitam um começo e fim na expressão, ou seja, o texto deve corresponder exatamente aquela
expressão.
Aplicando a expressão em alguns possíveis usuários, temos o resultado:

Validando username com regex!


Pode ou não aparecer (apenas uma vez)
Esse caso já vimos em alguns exemplos nos artigos anteriores. Para dizermos que o caractere pode ou não
estar presente na nossa regex, utilizamos o interrogação:

Lembra da Regex do CEP? Podemos ou não receber um hífen da máscara. Para resolver isso, utilizamos
o?:

\d{5}-?\d{3}

Vale ressaltar que esse caso tem o valor de zero (0) vezes ou uma (1) vez. Seria equivalente o “true” ou
“false”.

Pode não aparecer ou aparecer várias vezes


Diferente da interrogação, temos casos onde queremos dizer que tal caractere pode ou não aparecer, mas
quando ele aparecer, pode ser várias vezes. Para tal, utilizaremos o símbolo de asterisco (ou estrela):

*
Pelo menos 1 vez
Em casos onde queremos filtrar no mínimo uma vez, e não temos restrições máximas, podemos utilizar por
chaves:

{1,}

Mas podemos ser mais sucintos ainda, utilizando o operador de mais:

Para ver isso melhor, vejamos o target abaixo:

Raul Felipe de Melo;João Carlos Souza;Maria Zeferina

Nele, iremos filtrar os 3 nomes completos. O que sabemos?

1. O nome tem apenas letras (maiúsculas e minúsculas);


2. Existe espaço entre o nome e sobrenome

Para pegar as letras e espaços, utilizaremos uma classe de caractere (caso não tenha visto ainda o post sobre,
clica aqui) para considerar as letras e os espaços:

[A-Za-z\s]
Ainda não!

Perceba que selecionamos as letras maiúsculas e minúsculas e os espaços em branco. Entretanto, foi
selecionado cada letra e espaço individualmente. No fim, queremos que seja selecionado os blocos inteiros
que corresponderão aos nomes, correto? Então é aqui que entra o quantifier +:

[A-Za-z\s]+
éééééé….

Não, ainda não! =\

Fazendo uma pequena retrospectiva na aula sobre classes, quando definimos que queremos “word
characters”, a regra só vale de a até z, e não temos no alfabeto cedilha, tio no a e etc. Mas para resolver
isso, é só explicita-los:

Ae caramba! =D

Finalmente! (y)
Quantifiers são gananciosos!

É preciso tomar um certo cuidado com quantifiers! Por padrão, eles possuem um comportamento greedy
(adj. Ganancioso). Mas, o que isso significa na prática?

Lembra do exemplo dos nomes completos? O quantifier + (e todos os outros) entende da seguinte forma:

“Vou selecionar tudo o corresponder à essa expressão, até encontrar algo que não responda, aí eu paro!” —
 quantifier

E é exatamente isso que ele fez. Ele selecionou TUDO que era letras e espaços em branco, até se deparar
com o ponto-e-virgula e ser obrigado a parar a seleção. Meio abstrato né? O que ele faz é isso aqui:
Comportamento greedy
Mas Raul, como evitar esse comportamento? Eu quero meu quantifier preguiçoso!

Sempre que você quiser evitar esse comportamento — quiser que ele seja preguiçoso — após a declaração do
quantifier, basta passar uma interrogação. Assim, discurso dele vai passar para:

“Vou selecionar o texto até acontecer a primeira ocorrência correspondente à essa expressão!” — quantifier

Difícil imaginar um caso pra evitar esse comportamento? Vamos observar o target abaixo:
<h1 class="header" id="meu-titulo">Minha página</h1>

Por algum motivo obscuro, desejamos selecionar a tag h1 inteira, com seus atributos e tudo mais. Como
poderíamos resolver isso?

<h1.+>

Dessa forma, dizemos:

Por favor, regex engine, peguei os elementos que comece com <h1 tudo o que tiver, quantas vezes forem
necessários(.+) e pare até encontrar > .

Checkando o resultado:

Ainda não!
Não cara.. pior que não!

Pois é. Dessa maneira, ele pega a última ocorrência do sinal de maior (>). Mudando o quantifier de
ganancioso para preguiçoso com a interrogação, temos:

Aleluia!
Conclusão

Espero que tenha ficado claro o papel dos quantifiers e como eles serão úteis nas vossas expressões. Use e
abuse delas, principalmente das mais curtas (*,+,…).

Até a próxima!

Entendendo de uma vez por todas Expressões Regulares:


Parte 5— Capturando Grupos

“Senhor dos Anéis: A sociedade do Anel”

F ilhos de Zion, tudo na paz? Continuando nossa saga nas Expressões Regulares, hoje iremos abordar
uma funcionalidade que começa a dar vida e trazer uma real utilidade para as nossas expressões: Grupos de
caracteres.

Então, liga teu white noise e teu pomodoro e vamo que vamo!
Grupos de Caracteres: o que são?

Grupos de caracteres em expressões regulares são formas de agrupar expressões. Com eles, podemos
selecionar o que queremos ou não receber nos resultados.

Até agora, estamos definindo expressões sem grupo e quando temos um match, é no resultado inteiro da
expressão. Mas… e se quisermos pegar só um pedaço daquela expressão? Só uma parte em específico e o
resto podemos até descartar?

É justamente pra isso que serve o grupo. Observe o target abaixo:

<h1>Meu Titulo</h1>

Vamos imaginar que queremos pegar o valor do título entre as tags. Assim, podemos pensar da seguinte
forma:

1. Preciso definir que eu quero que venha um h1: <h1>


2. Como eu não sei o que virá no titulo, quero que apareça qualquer letra ou número (word character)
\w e também espaços em branco \s, 1 ou mais vezes: [\w\s]+
3. Por fim, fechamos a tag h1: <\/h1>

Resultado:
<h1>[\w\s]+<\/h1>

Full match!

Mas, não era bem o que a gente queria né? Queremos só o conteúdo do titulo e não as tags que ele está
inserido.

Utilizando os grupos

Para definir um grupo de caracteres, basta escrever uma expressão entre parênteses (“( )”). Dessa maneira,
começaremos a receber como resultado os valores do grupo, não só o full match como estamos
acostumados.

Continuando no exemplo do título, vamos separar cada bloco de código por grupos:
1. <h1> = (<h1>)
2. [\w\s]+ = ([\w\s]+)
3. <\/h1> = (<\/h1>)

Resultando em:

(<h1>)([\w\s]+)(<\/h1>)

Opa, novos resultados! \o

Viu só? Agora além de recebermos o valor full match da expressão, recebemos também valores de cada
grupo que definimos. E é aqui que a coisa começa a ficar interessante pra valer!

Mas Raul, a gente não queria somente o valor do título? Por que tá vindo as tags ainda?

Calma Jovem! A gente vai descobrir isso agora.


Non-capturing group

Como vimos no nosso exemplo, agora estamos pegando os valores dos grupos. Mas como solicitar à Regex
Engine para que NÃO traga o valor de algum grupo? Para faze-lo, basta no início do grupo digitar (?:) .

Assim, corrigindo a nossa expressão, temos:

(?:<h1>)([\w\s]+)(?:<\/h1>)

E como resultado temos:

Finalmente! =D

Como escapamos o valor dos grupos das tags, agora só temos o full match e o resultado do conteúdo da
nossa tag h1.
Diferentes cenários

Atingimos o nosso objetivo, mas, vamos um pouco mais afundo nisso.

Imagine que além de validar a tag h1, queremos considerar todos os tipos de titulo (de 1 a 6).

Bem, já sabemos fazer isso né? Basta utilizar uma classe de caractere, passando que queremos de 1 até 6:

<h[1-6]>

Alterando nossa expressão, temos:

(?:<h[1-6]>)([\w\s]+)(?:<\/h[1-6]>)

Resultando em:
Bem loco!

Conseguimos deixar um pouco mais dinâmico… Mas… como já diria o poeta:

“Algo errado, não está certo!” — desconhecido


Talvez você tenha percebido que temos uma possível falha em nossa expressão. Da maneira que está
definida, dizemos que:

Queremos pegar os valores entre as tags h (de 1 a 6) de abertura e fechamento!

Porém, observe o caso abaixo:

<h1>Meu titulo inválido</h4>

Todos nós sabemos que a tag de fechamento deve ser a mesma de abertura. Caso não seja, é um elemento
inválido! Entretanto, olha o resultado da nossa expressão:
õ.Ô
Chega…

Calma, calma, calma. Tem solução!

Backreferences

Backreference é uma forma de fazer referência à um grupo que já foi informado anteriormente, ou seja, é
uma forma de dizer à engine que queremos fazer referência (ter o mesmo valor aqui) do grupo “n”.

Grupo n? Que história é essa?

Número do grupo
Cada grupo que definimos ganha um número, que no caso seria sua posição na expressão. Esse número,
varia conforme a ordem de declaração, ou seja, o primeiro grupo ganha o número 1, o segundo ganha o
número 2 e assim sucessivamente.
Ordem dos grupos

Vale deixar claro que o que determina a ordem e os números de cada grupo é a ordem de precedência, ou
seja, se tivermos grupos dentro de grupos, a regex irá definir todas os grupos daquele aninhamento e depois
continuará para os outros que estão fora:

aninhamento de grupos
Fazendo uma analogia, lembra das aulas de matemática, onde temos várias expressões aninhadas e
precisamos resolver de fora pra dentro? É a mesma coisa:

1+((3*4)+2) = 1+(12+2) = 1+14 = 15

ATENÇÃO
Vale comentar um comportamento que pode fazer a gente quebrar muito a cabeça e acreditar que estamos
fazendo algo errado.

Quando definimos que o grupo será “non-capturing” (?:), além dele não aparecer nos resultados, ele
também não ganha uma numeração. Ou seja, você não conseguirá fazer referências à ele. =/

Fazendo referência à um grupo


Sabendo como é definido os números, para podemos definir que queremos o mesmo valor do grupo “n”,
basta saber o seu número e passarmos com a barra invertida (\).

Voltando pra resolver o último exemplo, queremos que quando a tag de abertura for h1, a tag de
fechamento também seja h1. Com o conceito de backrefence em mente, definiremos que o h[1-6] :

(?:<(h[1-6])>)
Agora, faremos a referência a ele. Como na ordem de precedência ele é o grupo número 1 (devido ao fato
de termos negado o pai), declaramos nosso que o backreference é igual a \1 :

([\w\s]+)(?:<\/\1>)

Juntando as duas partes:

(?:<(h[1-6])>)([\w\s]+)(?:<\/\1>)

Resultando em:

Tag de abertura e fechamento validada!

Perceba que agora blindamos a nossa regex contra um comportamento estranho. Infelizmente recebemos
um grupo não desejado, mas é o preço da referência por números.
De qualquer forma, nosso objetivo foi alcançado!

Yeah!

Conclusão

Ainda há mais algumas formas de fazer referência, como por exemplo por nome. Entretanto, essa
funcionalidade não é comum em todas as engines.

Grupos nos permitem dar uma complexidade e flexibilidade às nossas expressões. Assim, tenha em mente:
Sempre que precisar pegar algum resultado específico, utilize grupos!

Espero que tenha aprendido sobre o tema e até a próxima! =D


Entendendo de uma vez por todas Expressões
Regulares: Parte 6— Âncoras

F ala meu povo, tudo bem com vocês? Estamos quase fechando a série “Entendendo de uma vez por
todas Expressões regulares”.

Hoje iremos abordar um tema que pra mim, é um dos mais difíceis no que tange à Regex: Âncoras. Mas
antes, se você acabou de chegar por aqui e quer acompanhar desde o primeiro tópico, sugiro acessar o
primeiro artigo (introdução).

Chega de papo e vamos ao que interessa.

Mas, o que são?


Bom, no geral, âncoras servem para que você delimite um começo e um fim em uma expressão regular.
Basicamente você diz que a correspondência dessa expressão deve começar e terminar daquele jeito, e caso
não corresponda, já seja descartada.

Um pouco abstrato né? Vamos olhar esta string de teste bem simples:

aaa aaaa aaa aa

Se quiséssemos filtrar correspondências de 3 “a”, escreveríamos uma regex similar a:

a{3}

Porém, vamos observar o resultado:

Perceba que filtramos 3 “a” até do segundo conjunto, onde há 4. Mas pegamos apenas 3. E é exatamente
nos casos onde não queremos que essa correspondência ocorra que usamos as âncoras.
Tipos de âncoras

Existem algumas formas de definir âncoras, mas independentemente de qual o tipo, elas sempre terão um
mesmo padrão: âncora inicio + expressão + âncora fim .

Word boundary
Esse tipo de âncora é definido pela expressão \b . Ela indica que você deseja buscar uma expressão que não
comece e nem termine com letras.

Voltando no nosso exemplo simbólico, podemos usar esse tipo de âncora para resolver o problema:

Perceba que agora temos exatamente as correspondências que queríamos, pois, agora que definimos que a
expressão não pode terminar com uma letra, ele descarta o caso aaaa .
O inverso
Como já comentei nos tópicos anteriores, em Regex, geralmente quando queremos fazer uma negação,
usamos a letra maiúscula, ou seja, se eu digo que não quero que minha regex comece ou termine com letras
e números usamos \b , mas para dizer o contrário — que sim, queremos — basta utilizarmos o \B .

Ainda no exemplo anterior, combinado o \b com \B , podemos ter o seguinte resultado:

Perceba que agora definimos que a nossa expressão PODE começar com um caractere, mas não pode
terminar, tanto isso é verdade que o ultimo conjunto ( aaaab ) não é selecionado.
Início e Fim
Ainda temos âncoras que definem um início e um fim em nossas expressões, ou seja, o target (string alvo)
avaliado deve começar e terminar daquela forma, caso contrário, não teremos um match.

Esse tipo de âncora é definido por ^ e por $ , sendo o primeiro usado no início da expressão e o segundo no
fim:

^<minha-expressão>$

Para visualizar melhor o comportamento deste, vamos pensar em um caso hipotético:

Tenho uma aplicação que precisa fazer uma busca em uma pasta cheios de arquivos de extensão TXT, e
queremos filtrar um padrão especifico de nomenclatura dos arquivos. Digamos que essa nomenclatura seria
algo:

ano-nome_do_arquivo.txt

Quando fazemos a leitura dos arquivos na pasta, receberemos uma lista similar a essa:

Target:
2017-index_produto.txt
produtos.txt
2017-index_clientes.txt
clientes.txt
2016-users.txt

Bom, como eu sempre gosto de fazer, vamos montar a regex por partes:

 Para pegar o ano: \d{4}


 hífen obrigatório: -
 Nome do arquivo pode ter letras, números e underline (“_”) 1 ou + vezes: \w+
 extensão obrigatória: .txt

Juntando tudo, temos:

\d{4}-\w+.txt

E como resultado:
Entretanto, temos uma pequena falha nessa abordagem. Digamos que um arquivo com extensão .txts seja
colocado na pasta. Na hora de buscar os nomes dos arquivos, pegaríamos ele também:

Deu ruim!

Bom, não queremos então que os nossos matches comecem e terminem dessa maneira? Nem mais nem
menos? Então vamos usar âncoras de início e fim:

^\d{4}-\w+.txt$
Ih rapaz…

Eita… Calma.

Comportamento
Como eu disse anteriormente, o comportamento da âncora de início(^) e fim($) é definir que não teremos
MAIS NADA antes e nem depois, mas, implicitamente, o nosso alvo avaliado (string de nomes de arquivos)
possui uma quebra de linhas e esse é o motivo de simplesmente não ter funcionado.

Infelizmente, cada engine (motor) trata essa quebra de linhas de uma forma diferente. Caso você não seja da
turma do Javascript, sugiro dar uma olhada como a engine da sua linguagem favorita trata isso.
Além da nossa expressão, podemos passar flags que são basicamente configurações no modus operandi do
moto da Regex. A flag /g indica que essa expressão pode se repetir várias vezes, ou seja, ela terá o
comportamento de encontrar todas as correspondências no nosso alvo. Já a flag /m indica que queremos
considerar quebras de linhas.

No mundo Javascript, para aplicar essas flags você deve definir no fim da expressão. Entrarei em mais
detalhes no próximo artigo.

Por padrão, já estamos usando o /g , e agora combinaremos o /m para consertar nosso exemplo anterior:

Pronto, problema resolvido e casos tratados!


Conclusão
Hoje vimos um tópico que na minha opinião é um dos mais complicados de entender e aplicar, pela
variedade imensa e comportamentos diferentes em cada caso, mas sem dúvida alguma, muito útil para
resolver alguns problemas específicos. Espero que tenha ficado claro seu propósito e seu uso.

Caso tenha alguma dúvida ou sugestão de correção, fique à vontade para comentar aqui ou interagir comigo
das redes sociais.

Obrigado pela leitura e até mais!


Entendendo de uma vez por todas Expressões
Regulares: Parte 7— Regex no mundo JavaScript

F ala meu povo, tudo bem com vocês? Seguindo no penúltimo artigo da série regex, hoje falaremos
(finalmente) sobre como utilizar as expressões regulares no mundo JavaScript.

Mas antes de tudo, se você chegou direto nesse tópico e ainda não tem tanta familiaridade, da uma olhada
no post onde tudo começou.

Sem mais delongas, let's do it!

Declaração
Como a maioria dos objetos JavaScript, temos duas maneiras de declarar uma expressão regular, invocando
o construtor ou de maneira literal.

Constructor
A primeira forma (e menos usada), é chamando o construtor do objeto RegExp:

O primeiro argumento que o objeto recebe (nosso padrão), pode ser qualquer coisa (JavaScript feelings).
Porém, para o bom uso, ele deve ser uma string ou uma outra regex (sim, outra regex).

No caso da String, é necessário entender que as vezes precisaremos escapar os caracteres que possam ter
outro significado. Quem aqui nunca usou um \n pra dar aquela quebra de linha?

Então, se quisermos considerar que a barra seja de fato uma barra, e não um "efeito especial", precisamos
escapa-la com outra barra (._.):

const regex = new RegExp('\\w')

O segundo parâmetro é a flag que adiciona um comportamento em nosso motor da Regex. A mais popular e
já comentada bastante é a flag g , que permite que o motor continue procurando por todo o alvo o seu
padrão. Mas também existe outras bem importantes, como:

 i : Ignora o case, ou seja, não difere letras maiúsculas ou minúsculas;


 m : Permite que o padrão seja aplicado em múltiplas linhas. Bem útil no caso onde temos que aplicar
âncoras e ainda assim queremos aplicar em várias linhas;
 y : Força a regex só trazer os matches consecutivos, ou seja, se você tem um alvo que tem 2
resultados consecutivos e em seguida um caractere (ou conjunto) que não bate com seu padrão, ele só
traz os primeiros resultados.
 u : Habilita a capacidade da Regex engine de entender caracteres unicode e captura-los corretamente
(exemplo: 𝌆).

Esses são as flags que o JavaScript aceita, mas se você é de outra linguagem, talvez tenha mais tipos
diferentes.

Passando então a nossa expressão e a flag, temos uma declaração semelhante a essa:

const regex = new RegExp('\\w','g')

Literal
A segunda forma de declarar uma expressão regular é fazendo da forma literal, ou seja, passando uma
expressão entre duas barras / e em seguida, passando as flags:

const regex = /\w/g

Bem mais fácil, não?

Mas Raul, quando eu uso uma ou outra?


Bom, lembra quando eu disse que podemos trabalhar as expressões por partes? Vamos pensar em uma
expressão regular para capturar datas no formato DD/MM/YYYY:

Alvo

07/07/1995
14/08/1996
27/01/1937
08/01/1999
08/01/2099
08/21/2099
08/01/2399

Padrão

 Dia: [0-3]\d\/
 Mês: [01]\d\/
 Ano: [12][0129]\d{2}

Poderíamos juntar todas essas expressões e declara-la de forma literal:

const dataPattern = /[0-3]\d\/[01]\d\/[12][0129]\d{2}/g


Entretanto, perceba que se um dia você resolver que precisa alterar sua expressão, vai bater o olho e sentir
uma leve dificuldade de saber o que é o que. Então, como poderíamos resolver isso?

Bom, podemos declarar algumas variáveis com o pattern em string e depois concatena-los, passando para o
construtor:

Sim, tivemos que escapar cada barra invertida que encontramos, mas agora o código (apesar de maior) ficou
claro e caso precisamos alterar o pattern futuramente, não ficaremos confusos e com frio!

Métodos

Finalmente vamos começar a ver os métodos dos objetos do tipo RegExp. Assim como a maioria dos tipos
de dados em Javascript, RegExp também possui vários métodos, mas vamos nos focar nos dois principais,
exec e test . E talvez o segundo seja ainda mais útil que o segundo do ponto de vista do dia-a-dia.

Exec
Esse é o método que você irá utilizar quando você precisa recuperar o dado que está filtrando. Ele é aquele
tipo de função em que precisamos iterar através de um while , pois, a cada vez que você executa o método,
ele pula para o próximo resultado.
Para provar isso, veja o exemplo abaixo:

Perceba que no último console, chamamos o método novamente e ele foi para o próximo resultado da regex.

Aplicando o while para pegarmos todas as ocorrências, temos:

Quando o resultado de pattern.exec for undefined, automaticamente o while receberá false e sairá do loop.

Estrutura do resultado
Quando executamos o método exec , temos um um array e em seguida, esse array é atualizado e
transformado em um object com algumas informações. São elas:

1. O resultado encontrado. Você pode acessar através de: resultado[0]


2. O index, ou seja, em qual posição do alvo foi encontrado aquele resultado. Você pode acessar através
de: resultado.index
3. O input, ou seja, qual alvo que estava sendo avaliado naquele momento. Você pode acessar através de
resultado.input

Assim, perceba que é dentro do laço while que você extrairá seus dados.
Test
O método test, como disse anteriormente, talvez seja muito mais útil que o exec no dia-a-dia. Mas, porque?

Bem, o test apenas valida se aquele alvo contém o padrão que você definiu, retornando um true ou false .

Para entender melhor, vamos ver o exemplo abaixo:

Aqui, utilizamos o padrão de quebrar em partes a regex. Ficou um pouco confuso porque como visto no
artigo sobre meta-caractere (LINK) e grupos (LINK), o () é avaliado como criação de um grupo, logo,
precisamos escapa-lo com uma barra invertida ( \ ). Porém como já visto, em strings precisamos escapar a
barra invertida também.

O resultado do primeiro console é expressão criada. O do segundo é o teste de verdadeiro ou falso para
saber se aquele alvo obedece a nossa expressão. Dessa maneira, podemos ter algo parecido com:

if(regexTelefone.test(alvo)){
//Faça alguma lógica/ação
}else{
throw new Error('Número de telefone fora da máscara')
}
Mais e mais usos de Regex

Além dos métodos da própria regex, há outros tipos de dados que aceitam expressões regulares como
parâmetro ou usamos regex manipular resultados. Abaixo alguns deles:

String.replace
String.split

String.match
Array.filter
Conclusão

Com isso, fechamos a saga das expressões regulares (mentira, ainda tem um bônus). Espero ter consigo
fazer você pelo menos sentir interesse de usar pequenas expressões no dia-a-dia, afinal, podemos usa-las em
diversos lugares que não foram citados, como por exemplo, o próprio terminal.

Obrigado por ter acompanhado até aqui! E…

Você também pode gostar