Executando verificação de segurança...
5

Expressões Regulares (Regx) na linguagem Python

Fala Dev beleza, neste post quero falar um pouco a cerca das Expressões Regulares, basicamente sobre o que são, para que servem, e vou trazer ao longo deste New também programa que verifica se o Email digitado é valido ou não, usando o conceito das Expressões Regulares, de lembrar que é voltado a linguagem Python.

Oh de lembrar que o conteúdo que vou aqui explicar, está disponível no meu canal de Youtube: https://www.youtube.com/@setprogramacao, para você que deseja ver, e se fores por lá, dá uma força, se increvendo no canal e ajudado a crecer... vamos ao assunto do poster

O que são Expressões Regulares?

Expressões regulares (também conhecidas como regex ou regexp) são sequências de caracteres que definem um padrão de busca.

Importância e Uso

As Expressões regulares são amplamente utilizadas em Python e em outras linguagens de programação para realizar operações complexas de pesquisa, correspondência e manipulação de strings, criptografia, codificação de dados, processamento de linguagem neural.

As expressões regulares permitem realizar tarefas como validar formatos de strings, extrair informações específicas de uma string e substituir partes de uma string por outras.

Vou aqui listar alguns conceitos importantes sobre expressões regulares:

1. Metacaracteres
Os metacaracteres são caracteres especiais que possuem um significado especial em expressões regulares. Alguns exemplos de metacaracteres são: . ^ $ * + ? { } [ ] \ | ( ).

2. Sequências de Escape
Sequências de escape são combinações de caracteres que representam caracteres especiais ou classes de caracteres em expressões regulares. Por exemplo, \d representa um dígito e \s representa um caractere de espaço em branco.

3. Classes de Caracteres
As classes de caracteres são usadas para especificar um conjunto de caracteres permitidos em um determinado ponto da expressão regular. Por exemplo, [abc] corresponde a qualquer um dos caracteres 'a', 'b' ou 'c'.

4. Quantificadores:
Os quantificadores são usados para especificar a quantidade de ocorrências de um elemento em uma expressão regular. Alguns exemplos de quantificadores são: * (zero ou mais ocorrências), + (uma ou mais ocorrências) e ? (zero ou uma ocorrência).

Funções básicas das Expressões regulares

re.compile(): Compila uma expressão regular em um objeto de expressão regular.
re.match(): Verifica se uma expressão regular corresponde ao início de uma string.
re.search(): Verifica se uma expressão regular corresponde a qualquer parte de uma string.
re.findall(): Encontra todas as ocorrências de uma expressão regular em uma string.
re.sub(): Substitui todas as ocorrências de uma expressão regular em uma string por outra string.

Vamos agora criar o nosso pequeno programa que vai nos ajudara a verficar se um email fornecido é válido segundo este padrão: [email protected]

import re #importando a biblioteca

#Função principal
def validar_email(email):
    padrao = r'^[\w\.-]+@[\w\.-]+\.\w+$'
    return re.match(padrao, email) is not None

#Exemplo de uso
endereco_email = "[email protected]"
resultado = validar_email(endereco_email)
print(resultado)  # Output: True

Vamos a explicação do código, linha por linha:

import re

import re: Essa linha importa o módulo re, que é o módulo responsável pelo suporte a expressões regulares em Python. A importação dele é necessário para usar as funcionalidades de expressões regulares no código.

def validar_email(email):

def validar_email(email):: Essa linha define uma função chamada validar_email que recebe um parâmetro email. A função irá verificar se o email fornecido é válido de acordo com um padrão de expressão regular.

padrao = r'^[\w\.-]+@[\w\.-]+\.\w+$'

Nesta linha, é criada uma variável chamada padrao, que armazena a expressão regular usada para validar o email. A expressão regular é representada por uma sequência de caracteres precedida pelo prefixo r, que indica que a string é uma "raw string", o que significa que os caracteres de escape (como \n, \t, etc.) não serão processados, para você que já usa Python entende isso.

A expressão regular ^[\w\.-]+@[\w\.-]+\.\w+$ é usada para validar o email. Vamos analisar cada parte dela:

^: Indica que a expressão deve começar no início da string.
[\w\.-]+: Corresponde a um ou mais caracteres que podem ser letras, dígitos, sublinhados, pontos ou hifens.
@: Corresponde ao caractere "@".
[\w\.-]+: Corresponde a um ou mais caracteres que podem ser letras, dígitos, sublinhados, pontos ou hifens.
\.: Corresponde ao caractere "." (observe que o ponto é escapado com o caractere , pois o ponto é um metacaractere que corresponde a qualquer caractere em expressões regulares, mas aqui queremos corresponder literalmente ao caractere ponto).
\w+: Corresponde a um ou mais caracteres que podem ser letras, dígitos ou sublinhados.
$: Indica que a expressão deve terminar no final da string.

return re.match(padrao, email) is not None

return re.match(padrao, email) is not None: Essa linha utiliza a função re.match() do módulo re para verificar se o email fornecido corresponde ao padrão definido na variável padrao.
A função re.match() verifica se o padrão corresponde ao início da string fornecida (email).
Se a correspondência for bem-sucedida, re.match() retorna um objeto de correspondência que não é None, o que indica que o email é válido de acordo com o padrão.
Caso contrário, se não houver correspondência, re.match() retorna None, o que indica que o email não é válido.

endereco_email = "[email protected]"

endereco_email = "[email protected]": Essa linha define uma variável chamada endereco_email e atribui a ela o valor "[email protected]". Esse é o email que será verificado pela função validar_email.

resultado = validar_email(endereco_email)

resultado = validar_email(endereco_email): Essa linha chama a função validar_email com o valor da variável endereco_email como argumento. A função irá verificar se o email fornecido é válido de acordo com o padrão definido.

print(resultado)  # Output: True

print(resultado) # Output: True: Essa linha imprime o resultado retornado pela função validar_email. Se o email for válido, o resultado será True, caso contrário, será False.

Portanto, ao executar esse código, ele imprimirá True no console, pois o email "[email protected]" é válido de acordo com o padrão de expressão regular definido.

Alteração ao código

Caso você deseje passar o email de teste pelo input e não pela variável como fazemos no programa, aqui vai um pedaço de código que você pode usar para substituir esta linha: endereco_email = "[email protected]"

endereco_email = input('Digite o email para verificar: ')

Essa linha de código irá te permitir digitar o email que deseja verificar atravez do input no terminal.

A ressaltar que a ferramenta é muito poderosa com muitos recursos e possibilidades, eu recomendo estudares bastante (assim como a qualquer outra ferramenta), estudar e praticar mais para se tornar proficiente em seu uso. Você pode consultar a documentação oficial do módulo re em Python para aprender mais sobre os recursos disponíveis.

Espero que você tenha gostado dessa Matéria!

@settomoceme

Carregando publicação patrocinada...
3

Complementando, alguns detalhes:

\s não é somente para espaços em branco. Na verdade este atalho também corresponde a quebras de linha, TAB, e muitos outros caracteres.

Já os atalhos \d e \w também consideram caracteres de outros idiomas - em Python, o default é considerar quaisquer letras e dígitos definidos pelo Unicode (por exemplo, \d também considera o caractere ٨ - ARABIC-INDIC DIGIT EIGHT, entre muitos outros). O mesmo vale para \w, que considera letras de outros alfabetos (japonês, árabe, cirílico, etc). Então tem que considerar se quer estes caracteres no seu email.


Quanto a regex de email, tem alguns poréns. Por exemplo, ela considera que [email protected] e .@-._ são emails válidos, veja.

Isso porque [\w\.-]+ diz que pode ter uma ou mais ocorrências de letra, dígito, _, ponto ou hífen, mas ela não obriga que tenha cada um desses caracteres (se tiver somente um deles, já serve). Ou seja, --- e . já são suficientes para satisfazer esta expressão. Uma regex para validar email de forma mais assertiva é bem mais complicada.

Sobre o uso de regex para validar emails, também tem algumas coisas aqui, aqui, aqui, aqui e aqui (este último link tem algumas opções no final, só não recomendo a última regex).

Mas a meu ver a regex serviria apenas como um filtro inicial (por exemplo, para ver se algo se parece minimamente com um endereço de email). Mas no fim, uma validação mais confiável seria mandar um email com um link de confirmação, por exemplo. Aí vc garante não só que o email existe, como também que ele está em uso por alguém.

Não me entenda mal. Regex é legal, eu particularmente gosto bastante, mas nem sempre é a melhor solução. É muito fácil fazer uma regex que funcione para os casos válidos, mas é bem difícil fazer uma que também recuse os casos inválidos.

1

Excelente complemento (no caso do \s) pois espaço e tabs podem fazer grande diferença em um código a ser reconhecido.

1

Uso regex regularmente no meu dia a dia na área de segurança. Utilizo para identificar por indícios de malware, defacement, identificar software vulnerável, inventariar ativos, vazamento de informações pessoais etc.

Geralmente utilizo associado a alguma ferramenta open source ou comercial, mas também em códigos próprios em Python, Javascript e PHP.

Já utilizei também em um chatbot para encadear possíveis peguntas de um usuário.

Com a expressão regular abaixo você poderia identificar perguntas como:

  • Qual a resposta para tudo?
  • Explique o sentido da vida?
^(?=.*(\bqual\b|\bdiga\b|\bexplique\b))(?=.*(\bsignificado\b|\bsentido\b|\bresposta\b))(?=.*(\bvida\b|\buniverso\b|\btudo\b)).*$\gmiu

Como contribuição deixo 03 sites que particularmente acho bem interessantes para criar e analisar expressões regulares:

1

Não conheço todos os detalhes do seu caso de uso, o contexto da aplicação, etc. Mas enfim, seguem alguns comentários que espero que ajudem:

Sua regex também pegaria o texto Qual ônibos vai no sentido centro? Preciso comprar tudo isso hoje (veja). Isso porque ele pega qualquer texto que contenha determinadas palavras, a única exigência é que pelo menos uma de cada grupo apareça.

Na verdade, por causa dos lookaheads (os trechos que começam com (?=), elas podem até estar fora de ordem. Por exemplo, a frase Tudo faz sentido, diga também seria capturada pela regex, veja. Isso porque o lookahead só vê se algo existe à frente, mas depois volta para onde estava (no caso, ao início) e procura pelo restante da expressão. Ou seja, ele vê se existe "qual", "diga" ou "explique" em qualquer parte, depois volta e vê se existe "significado", "sentido" ou "resposta" (também em qualquer parte, não necessariamente depois de "qual"/"diga"/"explique"), e depois faz o mesmo para "vida", "universo" ou "tudo".

Para uma regex mais rígida, uma sugestão seria eliminar os lookaheads e também o uso de .* (pois é isso que permite "qualquer coisa", já que o ponto corrresponde a qualquer caractere, ou seja, até mesmo "frases" como sem sentido, -qual!@#$%-vida.123 dariam match, veja).

Uma sugestão - bem mais rígida - seria:

^(qual|diga|explique) (o s(ignifica|enti)do|a resposta) d(a vida|o universo|e tudo)[?.]?$

Agora a frase só pode começar com "qual", "diga" ou "explique". Como elas estão no início, não precisa mais do \b, pois o ^ já garante que elas devem estar no começo e não haverá nenhum outro caractere antes. E como depois tem um espaço, então também não precisa do \b depois, pois agora deve obrigatoriamente ter um espaço.

As palavras "significado" e "sentido" podem ser encurtadas para s(ignifica|enti)do, e o artigo "o" antes é para garantir que a frase fique correta ("explique o sentido", "diga o significado"). A outra alternativa é "a resposta". Depois temos outro espaço e o trecho final, que cobre as possibilidades "da vida", "do universo" e "de tudo" - como o d é comum a todos, deixei ele de fora, e depois dele tem as outras alternativas. E novamente, como há um espaço antes e depois, não precisa mais do \b.

No final, [?.]? indica que a frase pode ou não terminar com um ponto ou interrogação (pois entendo que "Explique o sentido da vida" não precisa de interrogação). Só pra deixar claro, [?.] indica que pode ser interrogação ou ponto, e o ? depois indica que é opcional. Veja aqui a diferença. Claro, se a pontuação não for opcional, use apenas [?.].

Eu habilitei a flag case insensitive para a frase poder começar com maiúscula (da mesma forma que vc fez). Só que aí também vai pegar frases como "diGA o SENtidO da VIda". Se a ideia é que somente a primeira letra possa ser maiúscula, melhor tirar a flag e trocar a regex para:

^([qQ]ual|[dD]iga|[eE]xplique) (o s(ignifica|enti)do|a resposta) d(a vida|o universo|e tudo)[?.]?$

Claro que agora ficou bem mais rígido, só vai aceitar frases que se encaixem perfeitamente nesta estrutura. Se quiser deixar mais flexível, vai ter que incluir mais elementos opcionais no meio, não tem jeito. Usar .* deixa mais simples, mas permite qualquer coisa, inclusive caracteres que não são letras nem pontuação. E deixar mais rígido elimina falsos positivos, mas dificulta a compreensão e futura manutenção. Não tem jeito, sempre é um trade-off, e depende do que vc quer considerar, dos dados que a aplicação recebe, etc.

Outra possível melhoria: por padrão, os parênteses criam grupos de captura, mas se vc não precisa disso (e só quer o match completo com a frase toda), basta trocar por grupos de não-captura, trocando a abertura de parênteses por (?:.


No fim, é como eu já disse no outro comentário, é fácil fazer uma regex que identifique os casos válidos, mas é difícil fazer uma que também ignore os inválidos.