Uma expressão regular (ou regex) é uma sequência de caracteres que podemos usar para atingir e manipular certos elementos em strings. Assim, podemos:
Este conceito é focado no uso de expressões regulares em JavaScript. Se você quer aprender a escrever expressões regulares, o Eloquent JavaScript pode ser um bom recurso.
💡 A variação de regex do JavaScript faz parte do padrão ECMA-262 da linguagem. Isso significa que você não precisa se preocupar com compatibilidade específica de navegador.
Em JavaScript, as expressões regulares são escritas na maioria das vezes no formato /pattern/modifiers, onde 'padrão' é a regex principal, e 'modificadores' são uma série de caracteres que podemos adicionar para indicar opções especiais (como superpoderes).
Ainda assim, temos duas formas de criar uma expressão regular:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
Nos dois casos, o JavaScript cria um objeto a partir da regex. Recomenda-se usar padrões imutáveis, com o literal como padrão.
O construtor RegExp pode ser usado em casos onde a regex vai mudar ou ainda não a conhecemos (como uma entrada).
As expressões regulares têm superpoderes opcionais chamados flags que permitem recursos adicionais. Essas flags podem ser usadas separadamente ou juntas, em qualquer ordem, e fazem parte da expressão regular.
Algumas das mais usadas são:
/g - Busca global/i - Não diferencia maiúsculas de minúsculas/m - Busca multilinhaVeja um exemplo simples:
const re = /home/gi;
const str = 'Home, sweet home.';
str.match(re);
// => ["Home", "home"]
O caractere g permite analisar todas as correspondências possíveis em uma string. Sem esse recurso, o JavaScript extrairia apenas a primeira correspondência de Home.
A flag de não diferenciação de maiúsculas e minúsculas /i nos dá flexibilidade na hora de encontrar um padrão. Assim, não importa se o que procuramos está em UPPERCASE ou lowercase.
Ao usar o construtor RegExp, a sintaxe para adicionar flags é diferente. Nesse caso, só precisamos 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 de strings.
O método test() é uma ótima forma de buscar e saber se um valor alvo existe em uma determinada string. Assim, ele retorna um valor Boolean, true ou false.
O método match() extrai a correspondência da expressão regular de uma determinada string. Retornando um array com informações e correspondências.
Quando usar um ou outro? Use test() quando você quer uma forma rápida de verificar um valor em uma string; use match() se precisar usar esse valor ou quiser mais informações sobre a correspondência.
O método test() executa uma busca por uma correspondência entre uma expressão regular e uma string especificada. Retorna true ou false.
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
Ok, mas e se quisermos obter os valores reais da busca com a expressão regular?
Em vez de retornar apenas um Boolean, com o método match() obtemos um array útil cujo conteúdo depende da presença ou ausência das correspondências encontradas.
Assim, somos capazes tanto de buscar quanto de 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 busca global /g está presente, em vez de obter apenas a única correspondência junto com informações úteis, como o índice ou a entrada, o método retorna 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 nos permite buscar um valor em uma determinada string e substituí-lo por um novo valor.
string.replace(searchValue, newValue);
O padrão para a busca 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 em 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 das contas, 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 limitado.
O método split() do JavaScript representa uma forma diferente de usar e manipular strings com expressões regulares.
Assim, usamos regex para dividir uma determinada string reconhecendo um padrão, por exemplo, str.split(/[,.\s]/). Esse 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']
Em relação ao desempenho, ambos criam um objeto RegExp. A principal diferença é com que frequência a regex é compilada:
Regular Expression Literal: uma vez, durante a análise e a compilação iniciais do códigoRegExp(): a cada vez 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, veja esta discussão no Stack Overflow.
RegExp(), você também precisa escapar aspas e escapar as barras invertidas duas vezes. Isso torna expressões regulares, que já são difíceis de ler e entender por natureza, ainda mais difíceis.