Expressões Regulares - Entenda o que são Lookahead e Lookbehind
Neste artigo vou tentar explicar o conceito de lookahead e lookbehind positivo e negativo. Trata-se de recursos avançados em expressões regulares que em algum momento poderão vir a salvar o teu dia.
Introdução
Posso comparar o momento em que você começa a se aprofundar e realmente entender expressões regulares como o momento em que um padawan Jedi aprende a manipular a força. A coisa é séria! Expressões regulares permitem você encurtar e muito o seu código, além de torná-lo bem mais legível e fácil de manter.
Lookahead e lookbehind são recursos onde você pode condicionar sua expressão com o que vem à frente ou antes da busca desejada, porém ele em si não será incluído no resultado da expressão.
Esse é um recurso avançado e ainda não está presente em todas as linguagens de programação. Por exemplo, JavaScript e Python sei que possuem suporte, já o sed ainda não.
Para um melhor entendimento, nada melhor que partirmos para a prática, certo?
Código em JavaScript. Tenho uma lista de nomes e, usando um positive lookahead, quero encontrar apenas pessoas com o sobrenome Fraga.
Salve o código como regex.js e execute-o com o node, deno ou o interpretador JavaScript de sua preferência:
node regex.js
Também é possível executar o código acima no console da ferramenta de desenvolvedores do seu navegador padrão ou até mesmo acessar um interpretador online como o http://jsconsole.com/.
Como resultado teremos:
[ 'Maria Joaquina', 'Silene' ]
Vamos analisar a regex criada:
/^.*(?=\sFraga)/gm
Salve o código como regex.js e execute-o com o node, deno ou o interpretador JavaScript de sua preferência:
node regex.js
Também é possível executar o código acima na ferramenta de desenvolvedores do seu navegador padrão ou até mesmo acessar um interpretador online como o http://jsconsole.com/.
Como resultado teremos:
[ 'Maria Joaquina', 'Silene' ]
Vamos analisar a regex criada:
/^.*(?<=da\s)Silva.*/gm
Se executado no código acima, teremos como retorno:
[ 'Anderson Silva', 'Vanderlei Silva' ]
O conceito parece confuso, mas a prática leva a perfeição. Comece a tentar usar lookahead e lookbehind em suas expressões regulares!
Lookahead e lookbehind são recursos onde você pode condicionar sua expressão com o que vem à frente ou antes da busca desejada, porém ele em si não será incluído no resultado da expressão.
Esse é um recurso avançado e ainda não está presente em todas as linguagens de programação. Por exemplo, JavaScript e Python sei que possuem suporte, já o sed ainda não.
Para um melhor entendimento, nada melhor que partirmos para a prática, certo?
Código em JavaScript. Tenho uma lista de nomes e, usando um positive lookahead, quero encontrar apenas pessoas com o sobrenome Fraga.
Lookahead Positivo
const nomes = ` Maria da Silva Mattos Pedro dos Santos Anderson Silva Maria Joaquina Fraga Vanderlei Silva Silene Fraga Braga Joana Dark da Silva ` const regex = /^.*(?=\sFraga)/gm console.log(nomes.match(regex))
Salve o código como regex.js e execute-o com o node, deno ou o interpretador JavaScript de sua preferência:
node regex.js
Também é possível executar o código acima no console da ferramenta de desenvolvedores do seu navegador padrão ou até mesmo acessar um interpretador online como o http://jsconsole.com/.
Como resultado teremos:
[ 'Maria Joaquina', 'Silene' ]
Vamos analisar a regex criada:
/^.*(?=\sFraga)/gm
- / e / são os delimitadores da expressão regular;
- ^ indica início da linha;
- .* vai capturar qualquer caractere exceto quebra de linha (.) zero ou mais vezes (*);
- (?=\sFraga) é o lookahead positivo. Essa expressão só trará resultados caso exista a palavra "Fraga" precedida de um espaço em branco (\s). Porém o lookahead não entra como resultado da expressão. Ela vai retornar tudo o que precede o lookahead;
- gm são as flags global e multiline, uma vez que nossa variável possui múltiplas linhas.
Lookahead Negativo
É o inverso do lookahead positivo, irá dar match somente com os nomes que não satisfizerem a condição. Basta trocar "?=" por "?!".const regex = /^.*(?!\sFraga)/gm
Lookbehind Positivo
const nomes = ` Maria da Silva Mattos Pedro dos Santos Anderson Silva Maria Joaquina Fraga Vanderlei Silva Silene Fraga Braga Joana Dark da Silva ` const regex = /^.*(?<=da\s)Silva.*/gm console.log(nomes.match(regex))
Salve o código como regex.js e execute-o com o node, deno ou o interpretador JavaScript de sua preferência:
node regex.js
Também é possível executar o código acima na ferramenta de desenvolvedores do seu navegador padrão ou até mesmo acessar um interpretador online como o http://jsconsole.com/.
Como resultado teremos:
[ 'Maria Joaquina', 'Silene' ]
Vamos analisar a regex criada:
/^.*(?<=da\s)Silva.*/gm
- / e / são os delimitadores da expressão regular;
- ^ indica início da linha;
- .* vai capturar qualquer caractere exceto quebra de linha (.) zero ou mais vezes (*);
- (?<=da) é o lookbehind positivo. Essa expressão só trará resultados caso exista a palavra "Silva" precedida de "da " (\s = espaço). Teremos como resposta todas as pessoas da família "da Silva", mas não as pessoas que são apenas "Silva";
- gm são as flags global e multiline, uma vez que nossa variável possui múltiplas linhas;
- como usei .* antes e depois do lookbehind, ele acabou sendo incluído no resultado da expressão.
Lookbehind Negativo
É o inverso do lookbehind positivo, irá dar match somente com os nomes que não satisfizerem a condição. Basta trocar "?<=" por "?<!".Se executado no código acima, teremos como retorno:
[ 'Anderson Silva', 'Vanderlei Silva' ]
O conceito parece confuso, mas a prática leva a perfeição. Comece a tentar usar lookahead e lookbehind em suas expressões regulares!
Muito bom.
Vou deixar aqui o link da página do "mestre Yoda" das expressões regulares, Aurélio Jargas:
https://aurelio.net/regex/
--
"There are lots of Linux users who don't care how the kernel works, but only want to use it. That is a tribute to how good Linux is." - Linus Torvalds