Uma expressão regular (ou Regex) é uma sequência de carateres que podemos usar para atingir e manipular determinados elementos em strings. Por isso, podemos:
Este conceito centra-se na utilização de expressões regulares em JavaScript. Se quiseres aprender a escrever expressões regulares, o Eloquent JavaScript pode ser um bom recurso.
💡 O dialeto de regex do JavaScript faz parte da norma ECMA-262 da linguagem. Isto significa que não tens de te preocupar com a compatibilidade específica de cada navegador.
Em JavaScript, as expressões regulares escrevem-se sobretudo no formato /pattern/modifiers, em que o «pattern» é a expressão regular principal e os «modifiers» são uma série de carateres que podemos acrescentar para indicar opções especiais (como superpoderes).
Ainda assim, há duas formas de criar uma expressão regular:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
Em ambos os casos, o JavaScript cria um objeto a partir da expressão regular. Recomenda-se usar padrões imutáveis e o literal como predefinição.
O construtor RegExp pode ser usado nos casos em que a expressão regular vai mudar ou ainda não a conhecemos (como uma entrada).
As expressões regulares têm superpoderes opcionais chamados flags que permitem funcionalidades adicionais. Estas flags podem ser usadas em separado ou em conjunto, em qualquer ordem, e fazem parte da expressão regular.
Algumas das mais usadas são:
/g - Pesquisa global/i - Não distinguir maiúsculas de minúsculas/m - Pesquisa em várias linhasEis um exemplo simples:
const re = /home/gi;
const str = 'Home, sweet home.';
str.match(re);
// => ["Home", "home"]
O caráter g permite-nos encontrar todas as correspondências possíveis numa string. Sem esta funcionalidade, o JavaScript teria extraído apenas a primeira correspondência, Home.
A flag de não distinção entre maiúsculas e minúsculas, /i, dá-nos flexibilidade ao procurar um padrão. Assim, não importa se o que procuramos está em UPPERCASE ou lowercase.
Ao usar o construtor RegExp, a sintaxe para acrescentar flags é diferente. Neste caso, basta passar as flags como segundo argumento.
Quando combinamos expressões regulares com as funções nativas do JavaScript, temos formas poderosas de manipular e obter dados a partir de strings.
O método test() é uma ótima forma de procurar e saber se um valor alvo existe numa dada string. Desta forma, devolve um valor boolean, true ou false.
O método match() extrai a correspondência da expressão regular de uma dada string, devolvendo um array com informações e correspondências.
Quando usar um ou outro? Usa o test() quando queres uma forma rápida de verificar um valor numa string; usa o match() se precisares de usar esse valor ou quiseres mais informações sobre a correspondência.
O método test() procura uma correspondência entre uma expressão regular e uma string especificada. Devolve true ou false.
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
Mas espera: e se quisermos obter os valores reais da pesquisa da expressão regular?
Em vez de devolver apenas um boolean, o método match() dá-nos um array útil cujo conteúdo depende da presença ou ausência das correspondências encontradas.
Assim, conseguimos tanto procurar como extrair informações de qualquer string. Por exemplo:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;
funnyQuote.match(regex1);
// => ["someone", index: 3, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]
funnyQuote.match(regex2);
// => null
Quando a flag de pesquisa global /g está presente, em vez de obter apenas a correspondência única juntamente com informações úteis como o índice ou a entrada, o método devolve todas as ocorrências presentes no array:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex3 = /if/gi;
funnyQuote.match(regex3);
// => ["If", "if"];
O método replace() do JavaScript permite-nos procurar um valor numa dada string e substituí-lo por um novo valor.
string.replace(searchValue, newValue);
O padrão de pesquisa da substituição pode ser uma única string ou uma expressão regular.
let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');
let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');
Além disso, podemos aplicar uma função na posição de substituição para fazer alterações adicionais a cada valor.
let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"
💡 No fim, a combinação de expressões regulares com o método
replace()é uma forma mais dinâmica de substituir elementos. Usar uma única string pode ser limitador.
O método split() do JavaScript representa uma forma diferente de usar e manipular strings com expressões regulares.
Assim, vamos usar uma expressão regular para dividir uma dada string reconhecendo um padrão, por exemplo str.split(/[,.\s]/). Este padrão será usado como separator.
const str = 'hello,user.how are.you';
const result = str.split(/[,.\s]/);
console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']
Quanto ao desempenho, ambos criam um objeto RegExp. A principal diferença está na frequência com que a expressão regular é compilada:
Regular Expression Literal: uma vez, durante a análise e compilação inicial do códigoRegExp(): sempre que um novo objeto é criado.Usar a sintaxe literal pode ser uma opção melhor, não só pelo desempenho, mas também pela simplicidade e legibilidade. Para mais detalhes, vê esta discussão no Stack Overflow.
RegExp(), também tens de escapar aspas e de usar duplo escape nas barras invertidas. Torna expressões regulares que já são difíceis de ler e compreender pela sua própria natureza ainda mais difíceis.