DicasGeralJavaScript

Aprenda Expressões Regulares ou Regex em JavaScript com exemplos

Na dica de hoje vamos mostrar o que é Expressões Regulares, padrões e como testar com exemplos em JavaScript.

Em ciência da computação, uma expressão regular ou “Regex” (ou os estrangeirismos regex ou regexp , abreviação do inglês regular expression) provê uma forma concisa e flexível de identificar cadeias de caracteres de interesse, como caracteres particulares, palavras ou padrões de caracteres. Expressões regulares são escritas numa linguagem formal que pode ser interpretada por um processador de expressão regular, um programa que serve um gerador de analisador sintático ou examina o texto e identifica as partes que casam com a especificação dada. O termo deriva do trabalho do matemático norte-americano Stephen Cole Kleene, que desenvolveu as expressões regulares como uma notação ao que ele chamava de álgebra de conjuntos regulares. Seu trabalho serviu de base para os primeiros algoritmos computacionais de busca, e depois para algumas das mais antigas ferramentas de tratamento de texto da plataforma Unix. (wikipedia).

O que são expressões regulares?
Expressões regulares são padrões que permitem descrever, corresponder ou analisar texto. Com expressões regulares, você pode fazer coisas como localizar e substituir texto, verificar se os dados de entrada seguem o formato necessário e outras coisas semelhantes.

Como criar uma expressão regular.
Em JavaScript, você pode criar uma expressão regular de duas maneiras:

Precisando de uma hospedagem de site ou de um servidor dedicado personalizado, seja para ambiente de teste, desenvolvimento ou de produção? E com um suporte de especialistas, que ti, ajudam a resolver os problemas o mais rápido possível? A SoloWeb tem o prazer em ti, ajudar com isso. Entre em contato conosco e faça uma cotação agora mesmo, acesse: www.soloweb.com.br.

Método #1: usando um literal de expressão regular. Isso consiste em um padrão entre barras. Você pode escrever isso com ou sem um sinalizador (veremos o que sinalizador significa em breve). A sintaxe é a seguinte:

let minhaVariavel = /pattern/  		//sem flags

let minhaVariavel = /pattern/flags;	//com flags

As barras /…/ indicam que estamos criando um padrão de expressão regular, da mesma forma que você usa aspas “ ” para criar uma string.

Método #2: usando a função construtora RegExp. A sintaxe é a seguinte:

let regConstructor = new RegExp(pattern [, flags])

Aqui, o padrão é colocado entre aspas, o mesmo que o parâmetro flag, que é opcional.

Então, quando você usa cada um desses padrões?

Você deve usar um literal regex quando souber o padrão de expressão regular no momento de escrever o código.

Por outro lado, use o construtor Regex se o padrão regex deve ser criado dinamicamente. Além disso, o construtor regex permite escrever um padrão usando um literal de modelo, mas isso não é possível com a sintaxe do literal regex.

O que são sinalizadores de expressão regular?
Sinalizadores ou modificadores são caracteres que permitem recursos avançados de pesquisa, incluindo pesquisa global e sem distinção entre maiúsculas e minúsculas. Você pode usá-los individualmente ou coletivamente. Alguns comumente usados ​​são:

g – é usado para pesquisa global, o que significa que a pesquisa não retornará após a primeira correspondência.
i – é usado para pesquisa que não diferencia maiúsculas de minúsculas, o que significa que uma correspondência pode ocorrer independentemente do uso de maiúsculas e minúsculas.
m – é usado para pesquisa de várias linhas.
u – é usado para pesquisa Unicode.
Vejamos alguns padrões de expressão regular usando ambas as sintaxes.

Como usar um literal de expressão regular:

//syntax => /pattern/flags

let regExpStr = "Olá mundo! olá aqui";

let regExpLiteral = /Olá/gi

console.log(regExpStr.match(regExpLiteral))

//saída => ['Olá', 'olá']

Observe que se não sinalizarmos o padrão com i, somente Olá será retornado.

O padrão /Olá/ é um exemplo de um padrão simples. Um padrão simples consiste em caracteres que devem aparecer literalmente no texto de destino. Para que ocorra uma correspondência, o texto de destino deve seguir a mesma sequência do padrão.

Por exemplo, se você reescrever o texto no exemplo anterior e tentar combiná-lo:

let regExpLiteral = /Hello/gi

let regExpStr = "oHell world, ohell there!"

console.log(regExpStr.match(regExpLiteral));

//saída => null

Obtemos null porque os caracteres na string não aparecem conforme especificado no padrão. Então, um padrão literal como /hello/, significa, h seguido por e, seguido por l, seguido por l, seguido por o , exatamente assim.

Como usar um construtor regex:

//syntax=> RegExp(pattern [,flags]) 

let regExpConst = new RegExp("xyz", 'g');  //com flag -g

let str = 'xyz xyz';

console.log(str.match(regExpConst));		

//saída: ['xyz', 'xyz'] 

Aqui, o padrão xyz é passado como uma string igual ao sinalizador. Além disso, ambas as ocorrências de xyz foram correspondidas porque passamos o sinalizador -g. Sem ele, apenas a primeira correspondência será retornada.

Também podemos passar padrões criados dinamicamente como literais de modelo usando a função construtora. Por exemplo:

let pattern = prompt('Informe o padrão?')  
//supondo que informou 'xyz'

let regExpConst = new RegExp(`${pattern}`, 'gi') 

let str = 'xyz XYZ';

console.log(str.match(regExpConst))

//saída: ['xyz', 'XYZ']

Como usar caracteres especiais de expressão regular.
Um caractere especial em uma expressão regular é um caractere com significado reservado. Usando caracteres especiais, você pode fazer mais do que apenas encontrar uma correspondência direta.

Por exemplo, se você deseja corresponder um caractere em uma string que pode ou não aparecer uma ou várias vezes, você pode fazer isso com caracteres especiais. Esses caracteres se encaixam em diferentes subgrupos que executam funções semelhantes.

Vamos dar uma olhada em cada subgrupo e os personagens que os acompanham.

Âncoras e Limites ou Anchors e Boundaries::
Âncoras são metacaracteres que correspondem ao início e ao fim de uma linha de texto que estão examinando. Você os usa para afirmar onde um limite deve estar.

Os dois caracteres usados ​​são ^ e $.

  • ^ corresponde ao início de uma linha e ancora um literal no início dessa linha. Por exemplo:
let  regexPattern = /^cat/;

console.log(regexPattern.test('cat and mouse'));   		
//saída=> true

console.log(regexPattern.test('The cat and mouse'))

// saída => false  - porque a linha não começa com cat

// sem o  ^  no padrão, a saída retornará true porque não declaramos um limite/boundary.

let regexPattern = /cat/;
console.log(regexPattern.test(The cat and mouse));		
//saída => true
  • $ corresponde ao final de uma linha e ancora um literal no final dessa linha. Por exemplo:
let regexPattern = /cat$/;

console.log(regexPattern.test('The mouse and the cat'));
// saída => true

console.log(regexPattern.test('The cat and mouse'));
// saída => false

Observe que ancora os caracteres ^ e $ corresponde apenas à posição dos caracteres no padrão e não aos próprios caracteres reais.

Limites de palavras são metacaracteres que correspondem à posição inicial e final de uma palavra uma sequência de caracteres alfanuméricos. Você pode pensar neles como uma versão baseada em palavras de ^ e $. Você usa os metacaracteres b e B para afirmar um limite de palavra.

  • \b corresponde ao início ou fim de uma palavra. A palavra é combinada de acordo com a posição do metacaractere. Aqui está um exemplo:
//syntax 1: /\b.../ onde ... representa uma palavra.

//procura por uma palavra que comece com o padrão informado
let regexPattern = /\bward/gi;

let text = “backward Wardrobe Ward”;

console.log(text.match(regexPattern));		
// saídat: ['Ward', 'Ward']

//syntax 2: /...\b/

//procura por uma palavra que termine com o padrão 'ward'
let regexPattern = /ward\b/gi;

let text = “backward Wardrobe Ward”;		

console.log(text.match(regexPattern));		
// saída: ['ward', 'Ward']

//syntax 3: /\b....\b/

//procura por uma palavra independente que começa e termina com o padrão informado
let regexPattern = /ward\b/gi;

let text = “backward Wardrobe Ward”;

console.log(text.match(regexPattern));	
//saída: ['ward']
  • \B é oposto de \b. Ele corresponde a todas as posições \b não.

Shortcodes para outros metacaracteres:
Além dos metacaracteres que vimos, aqui estão alguns dos mais usados:

  • \d – corresponde a qualquer dígito decimal e é um atalho para [0-9].
  • \w – corresponde a qualquer caractere alfanumérico que pode ser uma letra, um dígito ou um sublinhado. \w é abreviação de [A-Za-z0-9_].
  • \s – corresponde a qualquer caractere de espaço em branco.
  • \D – corresponde a qualquer não dígito e é o mesmo que [^0-9.].
  • \W – corresponde a qualquer caractere que não seja de palavra (que não seja alfanumérico) e é uma abreviação de [^A-Za-z0-9_].
  • \S – corresponde a um caractere de espaço não branco.
  • . – corresponde a qualquer caractere.

O que é uma Classe ou Class de Caracter?
Uma classe de caracteres é usada para corresponder a qualquer um dos vários caracteres em uma posição específica. Para denotar uma classe de caracteres, você usa colchetes [] e, em seguida, lista os caracteres que deseja corresponder dentro dos colchetes.

Vejamos um exemplo:

//encontra e combina uma palavra com duas grafias alternativas
let regexPattern = /ambi[ea]nce/

console.log(regexPattern.test(ambience))   	
//saída:true

console.log(regex.test(ambiance))		
//saída:true

//O padrão regex interpreta como: encontre a seguido por m, depois b,
//então i, então e ou a, então n, então c, e então e.

O que é uma classe de personagem negada?
Se você adicionar um símbolo de acento circunflexo dentro de uma classe de caractere como esta [^…] , ele corresponderá a qualquer caractere que não esteja listado entre colchetes. Por exemplo:

let regexPattern = /[^bc]at/

console.log(regexPattern.test(bat))      
//saída:false

console.log(regexPattern.test(cat))	
//saída:false

console.log(regexPattern.test(mat))	
//saída:true

O que é um intervalo?
Um hífen indica intervalo quando usado dentro de uma classe de caracteres. Suponha que você queira combinar um conjunto de números, digamos [0123456789], ou um conjunto de caracteres, digamos [abcdefg]. Você pode escrevê-lo como um intervalo como este, [0-9] e [ag], respectivamente.

O que é Alternância?
A alternância é outra maneira de especificar um conjunto de opções. Aqui, você usa o caractere pipe | para corresponder a qualquer uma das várias subexpressões. Qualquer uma das subexpressões é chamada de alternativa.

O símbolo de pipe significa ‘ou’, portanto, corresponde a uma série de opções. Permite combinar subexpressões como alternativas.

Por exemplo, (x|y|z)a corresponderá a xa ou ya, ou za. Para limitar o alcance da alternância, você pode usar parênteses para agrupar as alternativas.

Sem os parênteses, x|y|za significaria x ou y ou za. Por exemplo:

let regexPattern = /(Bob|George)Clan/ig

console.log(regexPattern.test('Bob Clan'));	
//saída: true

console.log(regexPattern.test('George Clan'));	
//saída: true

O que são quantificadores e ganância?
Os quantificadores indicam quantas vezes um caractere, uma classe de caracteres ou um grupo deve aparecer no texto de destino para que ocorra uma correspondência. Aqui estão algumas peculiares:

  • + corresponderá a qualquer caractere ao qual esteja anexado se o caractere aparecer pelo menos uma vez. Por exemplo:
let regexPattern = /hel+o/

console.log(regexPattern.test('helo'))		
//saída:true

console.log(regexPattern.test('hellllllllllo'))	
//saída:true

console.log(regexPattern.test('heo'))		
//saída:false
  • * é semelhante ao caractere +, mas com uma pequena diferença. Quando você anexa * a um caractere, significa que deseja corresponder a qualquer número desse caractere, incluindo nenhum. Aqui está um exemplo:
let regexPattern = /hel*o/

console.log(regexPattern.test(‘helo’))		
//saída:true

console.log(regexPattern.test(‘hellllo’))	
//saída: true

console.log(regexPattern.test(‘heo’))		
//saída:true

// aqui o * corresponde a 0 ou qualquer número de 'l'
  • ? implica ‘opcional’. Quando você o anexa a um caractere, significa que o caractere pode ou não aparecer. Por exemplo:
let regexPattern = /colou?r/

console.log(regexPattern.test(‘color’))		
//saída:true

console.log(regexPattern.test(‘colour’))	
//saída:true

//a ? depois do caractere u torna você opcional
  • {N}, quando anexado a um caractere ou classe de caractere, especifica quantos caracteres desejamos. Por exemplo /\d{3}/, significa combinar três dígitos consecutivos.
  • {N,M} é chamado de quantificador de intervalo e é usado para especificar um intervalo para a correspondência mínima e máxima possível. Por exemplo /\d{3, 6}/, significa corresponder um mínimo de 3 e um máximo de 6 dígitos consecutivos.
  • {N, } denota um intervalo aberto. Por exemplo /\d{3, }/, significa corresponder a 3 ou mais dígitos consecutivos.

O que é ganância em Regex?
Todos os quantificadores por padrão são gananciosos . Isso significa que eles tentarão corresponder a todos os caracteres possíveis.

Para remover este estado padrão e torná-los não-gananciosos, você anexa um ? ao operador como este +?, *?, {N}?, {N,M}?….. e assim por diante.

O que são Agrupamento e Retro-referência?
Anteriormente, vimos como podemos limitar o escopo da alternância usando os parênteses.

E se você quiser usar um quantificador como + ou * em mais de um caractere por vez digamos, uma classe ou grupo de caracteres? Você pode agrupá-los como um todo usando os parênteses antes de anexar o quantificador, assim como neste exemplo:

let regExp = /abc+(xyz+)+/i

console.log(regExp.test('abcxyzzzzXYZ'))       
//saída=>true

Aqui está o que o padrão significa: o primeiro + corresponde ao c de abc, o segundo + corresponde ao z de xyz e o terceiro + corresponde à subexpressão xyz, que corresponderá se a sequência se repetir.

A referência inversa permite que você corresponda a um novo padrão que é igual a um padrão correspondido anteriormente em uma expressão regular. Você também usa parênteses para referência inversa porque ele pode lembrar uma subexpressão previamente correspondida que ela inclui (ou seja, o grupo capturado).

No entanto, é possível ter mais de um grupo capturado em uma expressão regular. Portanto, para fazer referência a qualquer grupo capturado, você usa um número para identificar os parênteses.

Suponha que você tenha 3 grupos capturados em uma regex e queira fazer referência a qualquer um deles. Você usa \1, \2 ou \3, para se referir ao primeiro, segundo ou terceiro parênteses. Para numerar os parênteses, comece a contar os parênteses abertos da esquerda.

Vejamos alguns exemplos:

(x) corresponde a x e lembra a partida.

let regExp = /(abc)bar/ig;

//abc is backreferenced and is anchored at the same position as 
console.log(regExp.test('abcbarAbc'))		
//saída:true

console.log(regExp.test('abcbar'))		
//saída:false

(?:x) corresponde a x, mas não recupera a correspondência. Além disso, \n (onde n é um número) não se lembra de um grupo capturado anteriormente e corresponderá como um literal. Usando um exemplo:

let regExp = /(?:abc)bar/ig

console.log(regExp.test('abcbarabc'))		
//saída:false

console.log(regExp.test('abcbar'))		
//saída:true

A Regra de Fuga ou Escape Rule.
Um metacaractere deve ser escapado com uma barra invertida se você quiser que ele apareça como um literal em sua expressão regular. Ao escapar de um metacaractere em regex, o metacaractere perde seu significado especial.

Métodos de Expressão Regular.
O método test().
Usamos esse método várias vezes neste artigo. O método test() compara o texto de destino com o padrão regex e retorna um valor booleano de acordo. Se houver uma correspondência, ele retornará true, caso contrário, retornará false.

let regExp = /abc/ig

console.log(regExp.test('abcdef'))		
//saída:true

console.log(regExp.test('bcadef'))		
//saída:false

O método exec().
O método exec() compara o texto de destino com o padrão regex. Se houver uma correspondência, ele retornará uma matriz com a correspondência caso contrário, retornará nulo. Por exemplo:

let regExp = /abc/ig

console.log(regExp.exec('abcdef'))	
//saída:["abc"]

console.log(regExp.exec('bcadef'))
//saída:null

Além disso, existem métodos de string que aceitam expressões regulares como um parâmetro como match(), replace(), replaceAll(), matchAll(), search()e split().

Exemplos de regex.
Aqui estão alguns exemplos para reforçar alguns dos conceitos que aprendemos neste artigo.

Primeiro exemplo: como usar um padrão regex para corresponder a um endereço de e-mail:

Vamos interpretar o padrão. Aqui está o que está acontecendo:

  • / representa o início do padrão de expressão regular.
  • ^ verifica o início de uma linha com os caracteres na classe de caracteres.
  • [(\w\d\W)+ ]+ corresponde a qualquer palavra, dígito e caractere não-palavra na classe de caracteres pelo menos uma vez. Observe como os parênteses foram usados ​​para agrupar os caracteres antes de adicionar o quantificador. Isto é igual a isto [\w+\d+\W+]+.
  • @ corresponde ao literal @ no formato de email.
  • [\w+]+ corresponde a qualquer caractere de palavra nesta classe de caracteres pelo menos uma vez.
  • . escapa do ponto para que apareça como um caractere literal.
  • [\w+]+$ corresponde a qualquer caractere de palavra nesta classe. Além disso, essa classe de caractere está ancorada no final da linha.
  • /- termina o padrão.

Certo, próximo exemplo: como fazer a correspondência de um URL com o formato http://example.com ou https://www.example.com:

let pattern = /^[https?]+:\/\/((w{3}.)?[\w+]+)\.[\w+]+$/gi

console.log(pattern.test('https://www.example.com')
//saída: true
                        
console.log(pattern.test('http://example.com')
//saída: true
                         
console.log(pattern.test('https://example')
//saída:false

Vamos também interpretar esse padrão. Aqui está o que está acontecendo:

  • /…../ representa o início e o fim do padrão regex.
  • ^ afirma para o início da linha.
  • [https?]+ corresponde aos caracteres listados pelo menos uma vez, mas ? torna o ‘s’ opcional.
  • : corresponde a um ponto e vírgula literal.
  • \/\/ escapa das duas barras.
  • (w{3}.)? corresponde ao caractere w 3 vezes e ao ponto que segue imediatamente. No entanto, este grupo é opcional.
  • [\w+]+ corresponde ao caractere nesta classe pelo menos uma vez.
  • . escapa do ponto.
  • [\w+]+$ corresponde a qualquer caractere de palavra nesta classe. Além disso, essa classe de caractere está ancorada no final da linha.

Esperamos ter ajudado com o artigo, que analisamos os fundamentos das expressões regulares. Também explicamos alguns padrões de expressão regular e praticamos com alguns exemplos.

Esperamos ter ajudado com mais esta dica, e siga nos, nas redes sociais para mais tutoriais, e se precisar de nossa ajuda estamos a disposição: www.soloweb.com.br.

E lembrando que a SOLOWEB além de oferecer Hospedagem de Sites, Servidores Dedicados, Servidores VPS com o menor custo do Brasil, também desenvolve soluções de software e realiza gerenciamento e monitoramento de servidores para sua empresa, faça uma cotação sem custo, acesse: www.soloweb.com.br