E aí pessoas!

Eu gostaria de começar agradecendo mais uma vez ao Chico por ter autorizado a exposição do diálogo presente neste post. Valeu molecão! É nóis!

Agora, deixe-me contar a história:

Estávamos no ônibus eu e o Chico…

imagem do Professor Girafales dizendo que o burro vai na frente!

P.S.: Se não entendeu a imagem, procure no YouTube por “Eu e Quico, Quico e eu”.

Voltando à história:

Estávamos eu e o Chico no busão, subindo a serra em direção a São Paulo pela Rodovia dos Imigrantes. Estávamos de boa, trocando uma ideia, até que ele pergunta:

Chico: - Não sabia que era permitido pular de asa delta aqui na serra.

Eu olhei pela janela e não encontrei nada. Curioso, eu questionei o Chico:

Eric: - Onde é que tu tá vendo uma asa delta?

Chico aponta pra suposta asa delta e fala:

Chico: - Ali pô!

Eu olho, começo a rachar o bico e falo:

Eric: - Porra Chico! Aquilo ali é um URUBU!

Sensacional! Eu ri muito, senti como se o meu pâncreas fosse saltar pra fora do corpo de tanta risada.

Enfim… Esta historinha será o texto onde faremos os matchings de hoje.

Para começar, vamos colar o texto no RegExr e procurar pelo “Chico”:

imagem ilustrando matching com "Chico"

Como podem ver, eu enumerei as linhas, pra facilitar sua identificação. A cor azul indica que houve algum match na linha e a cor vermelha indica que não houve nenhum match na linha.

A missão pra hoje é descobrir quais são as linhas que contém o que foi que o Chico disse, as falas dele. Sendo mais específico, queremos identificar as linhas 2 e 6.

Vamos pensar sobre o padrão que temos que capturar…

As linhas que representam as falas começam com o nome da pessoa seguido de “:” (dois pontos). Portanto, as falas do chico começam com Chico:. Vamos ver como fica na regex:

imagem ilustrando matching com "Chico:"

Estamos quase lá! Conseguimos match nas duas linhas que começam com “Chico:”. Mas também houve um match no final da linha 3.

O que está faltando, é um meio de informar pra regex que ela deve dar match na string “Chico:” somente no ínicio da linha.

Para passar esta informação pra expressão, nós utilizamos o metacaractere ^ (circunflexo), cuja função é bater com a posição inicial da linha.

Isto mesmo, o circunflexo é do tipo que bate com uma determinada posição, por isto, é classificado como um operador posicional. Diversas fontes usam o termo âncora para se referir a este tipo de operador. Ambos são válidos, fique a vontade pra chamá-lo com o nome que achar melhor.

Sabendo que o circunflexo bate com o início da linha, vamos adicioná-lo à expressão:

imagem ilustrando matching fail com "^Chico:"

Aí deu erro, mas na minha máquina funciona!

Não houve match. Mas não se preocupem, a regex não está errada e o RegExr não está bugado. É simplesmente uma questão de configuração.

O padrão do circunflexo no RegExr é bater com a posição inicial do texto como um todo, independente da linha. Para que o circunflexo considere o início de cada nova linha, precisamos passar para o modo multilinha. Fazemos isso marcando a opção multiline no menu flags. Veja na figura abaixo:

imagem ilustrando flag multiline sendo setada no RegExr"

Com o multiline ativo, temos o match conforme esperado:

imagem ilustrando matching com "^Chico:"

A missão de hoje não foi comprida e já está cumprida.

Mas não quero encerrar sem mostrar o oposto do circunflexo, que é o $ (cifrão). Se o circunflexo bate com o início da linha, o cifrão bate com o fim da linha.

Pra ver como age o cifrão, vamos aplicar a regex [A-Za-z]+\. pra capturar as palavras que antecedem um ponto qualquer:

imagem ilustrando matching com ponto

Vemos 3 trechos que deram match. Agora, vamos alterar a expressão pra capturar as palavras que antecedem um ponto final:

imagem ilustrando matching com ponto no fim da linha

Com o cifrão no final, a regex capturou apenas o “serra.”, pois ele está no fim da linha.

Vale lembrar que, assim como o circunflexo, o cifrão só tem efeito em cada linha se a flag multiline estiver marcada. Isso quando estamos falando do RegExr, que usa a API do JavaScript. Algumas APIs e ferramentas já apresentam esse comportamento por padrão, sem a necessidade de setar nenhum flag. Na dúvida, sempre consulte a documentação da ferramenta que estiver usando.

É isso aí pessoas! Hora do café!

Mas primeiro… Tabela de operadores atualizada:

Itens que batem com um caractere
MetacaractereNomeFunção
.pontocaptura qualquer caractere
[ ]colchetes ou listacaptura qualquer um dos caracteres listados
\barra invertidatorna literal o metacaractere à sua direita
Modificadores que determinam quantidade: Quantificadores
MetacaractereNomeFunção
?interrogaçãotorna o elemento à sua esquerda opcional
*asteriscotorna o elemento à sua esquerda opcional e permite múltiplas ocorrências
+maiselemento à sua esquerda deve aparecer uma ou mais vezes
{n,m}chaveselemento à sua esquerda deve aparecer no mínimo n e no máximo m vezes
Operadores que batem com uma posição: Âncoras
MetacaractereNomeFunção
^circunflexobate com a posição incial do texto
$cifrãobate com a posição final do texto
Outros (grupo dos que ficaram sem grupo)
MetacaractereNomeFunção
( )parêntesesdelimita escopo para outros operadores

Valeu e Falou…


Ela é gulosa… Estúpida! (anterior) (próximo) Feliz Natal… digo… Feliz Páscoa!