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.
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!