Lookahead e Lookbehind
Neste capítulo, exploraremos como encontrar correspondências em JavaScript usando Lookahead e Lookbehind com exemplos práticos.
Compreender os tópicos avançados das expressões regulares em JavaScript é benéfico para qualquer desenvolvedor que deseje aprimorar suas habilidades de programação. Entre os recursos mais avançados e poderosos dessa área estão as asserções de lookahead e lookbehind. Essas asserções permitem que os desenvolvedores pesquisem padrões em texto sem incluir esses padrões no resultado. Este guia tem como objetivo oferecer uma exploração aprofundada das asserções de lookahead e lookbehind em JavaScript, com diversos exemplos práticos.
As expressões regulares podem ser complexas e podem existir casos extremos. Isso é especialmente verdadeiro quando você utiliza conceitos avançados como Lookahead e Lookbehind. Use testadores de regex online ou escreva testes unitários para validar suas expressões em uma variedade de cenários de entrada e garantir que se comportem conforme o esperado.
Introdução às Asserções de Lookahead e Lookbehind
As asserções de lookahead e lookbehind são asserções de largura zero, o que significa que correspondem a uma posição dentro da string em vez de caracteres reais. Elas nos permitem verificar se um determinado padrão existe ou não existe em um ponto específico da string. Observação: os mecanismos JavaScript modernos (ES2018+) suportam asserções lookbehind de comprimento variável, embora alguns ambientes mais antigos possam exigir padrões de comprimento fixo.
Existem quatro asserções, formadas pela combinação de direção (adiante/atrás) com polaridade (positiva/negativa):
| Asserção | Sintaxe | Significado |
|---|---|---|
| Lookahead positivo | (?=...) | O padrão deve seguir este ponto |
| Lookahead negativo | (?!...) | O padrão não deve seguir este ponto |
| Lookbehind positivo | (?<=...) | O padrão deve preceder este ponto |
| Lookbehind negativo | (?<!...) | O padrão não deve preceder este ponto |
Por que "largura zero" é importante
Como as asserções correspondem a uma posição e não a caracteres, o texto que elas verificam nunca é incluído na correspondência e a posição de leitura do mecanismo de regex não avança além dele. É exatamente isso que as torna úteis: você pode exigir contexto ao redor de uma correspondência sem que esse contexto faça parte do resultado. O trecho abaixo mostra a diferença entre um grupo de captura real e um lookahead — ambos verificam que pie segue apple, mas apenas o grupo consome o texto:
Se você não conhece a sintaxe de grupo (...), consulte Grupos de captura — o lookaround usa os mesmos parênteses, mas adiciona ?=, ?!, ?<= ou ?<! logo após o colchete de abertura.
Lookahead Positivo
Uma asserção de lookahead positivo verifica a existência de um determinado padrão à frente da posição atual na string. É denotada por (?=...). O exemplo a seguir usa um lookahead positivo para encontrar a palavra "apple" seguida pela palavra "pie":
O lookaround de regexp JavaScript corresponde a caracteres
Lookahead Negativo
Uma asserção de lookahead negativo verifica a ausência de um determinado padrão à frente da posição atual. É denotada por (?!...). O exemplo a seguir usa um lookahead negativo para encontrar a palavra "apple" que não é seguida pela palavra "pie":
O lookahead negativo de regexp JavaScript
Lookbehind Positivo
Uma asserção de lookbehind positivo verifica a existência de um determinado padrão atrás da posição atual na string. É denotada por (?<=...). Abaixo está um exemplo de código para encontrar a palavra "pie" precedida pela palavra "apple":
O lookbehind positivo de regexp JavaScript
Lookbehind Negativo
Uma asserção de lookbehind negativo verifica a ausência de um determinado padrão atrás da posição atual. É denotada por (?<!...). Aqui está um exemplo para encontrar a palavra "pie" que não é precedida pela palavra "apple":
Lookahead e Lookbehind
Aplicações Práticas de Lookahead e Lookbehind
Validando a Força de Senhas
Garantir senhas fortes é um requisito comum em aplicações web. As asserções de lookahead podem ser usadas para validar diversas condições de senha sem consumir caracteres.
Aqui, cada (?=...) é um requisito separado verificado desde o início da string. Como cada lookahead tem largura zero, todos os quatro percorrem o mesmo texto de forma independente sem interferir uns nos outros, e o [A-Za-z\d@$!%*?&]{8,} final é o que realmente consome a senha. As âncoras ^ e $ fixam a verificação em toda a string, e {8,} é um quantificador que exige pelo menos oito caracteres.
Formatando e Analisando Dados
As asserções de lookahead e lookbehind podem auxiliar na formatação e análise de estruturas de dados complexas. Um bom exemplo é a inserção de vírgulas em uma string de números para melhorar a legibilidade:
Isso funciona substituindo cada posição vazia (\B, um limite de não-palavra) que é seguida por um grupo de três dígitos repetido até o final do número. O (?!\d) ao final garante que apenas correspondemos posições onde os dígitos restantes são divisíveis por três, de modo que nenhuma vírgula seja inserida no início.
Extraindo o valor de um preço
O lookbehind é ideal para capturar um valor que aparece após um marcador conhecido sem capturar o próprio marcador. Aqui extraímos o valor numérico que segue o sinal $:
O lookbehind (?<=\$) exige um $ imediatamente antes do número, mas o exclui do resultado, de modo que cada correspondência contém apenas o valor numérico. Compare isso com o uso de um grupo de captura — um grupo forçaria você a ler o valor em match[1], enquanto o lookbehind coloca o valor diretamente na correspondência.
Agindo apenas quando algo não vem a seguir
O lookahead negativo permite agir em uma posição com base no que não vem a seguir. Este exemplo substitui hello por HI somente quando não é seguido por world:
Tópicos Relacionados
- Grupos de captura — os parênteses sobre os quais a sintaxe de lookaround é construída.
- Âncoras: início e fim da string —
^e$, frequentemente combinados com lookahead em validações. - Quantificadores, +, *, ? e
{n}— controlando a repetição dentro e fora das asserções. - Quantificadores gulosos e preguiçosos — como o comprimento da correspondência interage com o lookaround.
Conclusão
Dominar as asserções de lookahead e lookbehind em JavaScript pode melhorar significativamente sua capacidade de manipular e analisar strings. Essas ferramentas poderosas oferecem a flexibilidade de verificar padrões sem consumir caracteres, tornando-as indispensáveis para tarefas complexas de processamento de texto. Ao aproveitar essas asserções, os desenvolvedores podem criar expressões regulares mais eficientes e eficazes, resultando em um código mais limpo e de fácil manutenção.