O que é Python RegEx? Vamos falar a fundo sobre Python RegEx, abordando problemas práticos para introdução às expressões regulares, além de mostrar o poder que temos ao utilizarmos esse conceito com uma linguagem de programação.
Utilizaremos Python para as demonstrações práticas, mas a beleza do regex é que, por ser um conceito base para a ciência da computação, qualquer linguagem de programação possui funções/bibliotecas para sua utilização!
10 Livros de Python para ser um especialista
O que é Python RegEx?
RegEx é uma abreviação do termo “Regular Expression” e é definida, basicamente, como uma notação utilizada para representar padrões em cadeias de caracteres, as strings.
Sabe aqueles conceitos e/ou ferramentas que, num primeiro momento, parecem muito complexos, mas que, com o decorrer do aprendizado, se mostram muito simples e até mesmo triviais?
Esse é o caso quando o assunto é regex! Apesar de usarmos Python para as demonstrações práticas, você pode usar qualquer outra linguagem!
Um breve contexto histórico
Sei que o interessante mesmo é a prática, mas também é importante saber que o conceito de expressões regulares surge da teoria das linguagens formais e da teoria dos autômatos, ambas são parte do que chamamos de teoria da computação.
Cada uma das teorias citadas pode ser abordada em um artigo exclusivo, mas de maneira simplória, é – ou foi – através delas que os conceitos da matemática convergiram para o que hoje conhecemos como ciência da computação, alicerce fundamental para a Tecnologia da Informação.
Conceitos iniciais de sintaxe
Agora sim, partindo para a prática, vamos entender alguns conceitos iniciais de sintaxe muito simples.
Utilizarei a regex101, ferramenta de construção e análise de regex, para demonstrar na prática a utilização dos conceitos. Utilize os links para a visualização de exemplos práticos de cada tópico.
Caracteres abrangentes vs caracteres precisos
Lembre-se, você está escrevendo uma sequência padrão de caracteres e cada caractere que você escreve pode ser classificado de duas formas:
- Como um caractere preciso: “a” se refere especificamente ao caractere “a”;
- Como um metacaractere: “.” é o que chamamos de coringa e se refere a qualquer caractere.
Se você quer buscar especificamente pelo caractere “.” precisa usar o padrão “\.”. (tente fazer a modificação e buscar especificamente por “.”).
Ao longo dos próximos tópicos vou apresentar alguns outros metacaracteres que nos ajudam a compor nosso padrão de busca.
Marcadores de início e fim de linha (^ e $)
Esses marcadores indicam que você só trata como relevantes ocorrências do padrão escolhido no início ou no fim das linhas. Exemplos:
^Python – Encontra qualquer string que esteja em início de linha e contenham os caracteres “Python”.
Python$ – Encontra qualquer string que esteja em fim de linha e contenham os caracteres “Python”.
Marcadores de quantidade (* + ? e {})
Marcadores de quantidade indicam repetições de um caractere ou de uma sequência de caracteres em um padrão. Exemplos:
Pyt* – Encontra strings com a sequência de caracteres “Py” seguida de zero ou mais ocorrências do caractere “t”.
Pyt+ – Encontra strings com a sequência de caracteres “Py” seguida de uma ou mais ocorrências do caractere “t”.
Pyt? – Encontra strings com a sequência de caracteres “Py” seguida de zero ou uma ocorrência do caractere “t”.
Pyt{3} – Encontra strings com a sequência de caracteres “Py” seguida de exatamente 3 ocorrências do caractere “t”.
Pyt{2, 4} – Encontra strings com a sequência de caracteres “Py” seguida de 2 a 4 ocorrências do caractere “t”.
Pyt{3,} – Encontra strings com a sequência de caracteres “Py” seguida de 3 ou mais ocorrências do caractere “t”.
Para utilizar uma sequência de caracteres na repetição, utilize () para demarcar a sequência a que você quer se referir. Exemplo:
Py(th)* – Encontra strings com a sequência de caracteres “Py” seguida de zero ou mais ocorrências do da sequência “th”.
Marcador de alternativa ou operador OR ( | )
Este marcador é utilizado para inserir no padrão uma alternativa de caractere ou sequência de caracteres. Na prática, funciona como o operador OR na sequência expressa no padrão. Exemplos:
Pyt|hon – Encontra strings com a sequência de caracteres “Pyt” ou strings com a sequência de caracteres “hon”.
Py(t|h) – Encontra strings com a sequência de caracteres “Py” seguida do caractere “t” ou do caractere “h”.
Py(t|h|o) – Encontra strings com a sequência de caracteres “Py” seguida do caractere “t” ou do caractere “h” ou do caractere “o”.
Marcador de definição de Conjuntos ([ ])
Utilizando este marcador, podemos definir um conjunto de caracteres para a composição de padrões. O último exemplo do tópico anterior pode ser reescrito da seguinte forma:
Py[tho] – Encontra strings com a sequência de caracteres “Py” seguida de um caractere pertencente ao conjunto (t, h, o).
Outros exemplos comuns de conjuntos utilizados:
Py[0-9] – Encontra strings com a sequência de caracteres “Py” seguida de um caractere pertencente ao conjunto de dígitos de 0 a 9.
Py[a-z] – Encontra strings com a sequência de caracteres “Py” seguida de um caractere pertencente ao conjunto de caracteres alfabéticos de “a” a “z”.
Marcadores de classes de caracteres (\w, \d, \s e .)
\w – Representa um caractere alfanumérico, incluindo ocorrências maiúsculas e minúsculas das letras e o caractere “_”.
\d – Representa um caractere numérico e equivale a definição do conjunto [0-9]
\s – Representa um espaço em branco, incluindo tabulações e quebras de linha
. – Como já mencionado, este caractere é utilizado como coringa e representa qualquer caractere.
A utilização de \W, \D e \S serve como negação de suas correspondentes descritas acima. \W vai encontrar, por exemplo, qualquer caractere que não seja relevante para \w.
Casos de uso
As formas mais comuns da utilização de Python RegEx é na busca de strings que obedecem a um padrão em um texto ou página na web.
Os cada vez mais populares scripts de web scraping são exemplos de uso mais atual, mas desde os mais antigos editores de texto, as expressões regulares eram usadas nos algoritmos de busca e substituição de palavras.
Algumas expressões regulares usadas em problemas cotidianos são:
- Padrão para CPF;
- Padrão para CEP;
- Padrão para telefones;
- Padrão para endereços de email;
- Padrão para domínios DNS.
Python RegEx: O poder do Regex em conjunto com Python
Ok. Você deve estar se perguntando “E o Python, quando entra?”.
Por si só, Regex é uma forma flexível de se descrever padrões de interesse em strings. Aliar isso a linguagem de programação torna possível a criação de algoritmos, scripts e programas que realmente se caracterizam como uma solução.
Em Python, a biblioteca utilizada para manipulação de regex é a re:
>>> import re
Em Python 3, a simples utilização de r” ” é o suficiente para criar um padrão de Python RegEx. Dessa forma se queremos atribuir a uma variável x o padrão do nosso primeiro exemplo, “Pyt*” podemos utilizar:
>>> x = r"Pyt*"
A partir daí você pode fazer uso dos métodos da biblioteca citada para manipulação de strings através de expressões regulares.
Os tópicos a seguir descrevem os métodos mais comumente utilizados da biblioteca re.
Método re.match(padrão, string, flags=0)
Esse método é utilizado para validar se uma string contém determinado padrão. É preciso passar dois parâmetros para o seu correto funcionamento, não utilizaremos o parâmetro flags para simplificar a demonstração.
Se quisermos criar uma função que valida a estrutura de um CPF por exemplo (não incluindo a relação matemática que os dígitos do CPF devem conter entre si), podemos declará-la da seguinte forma:
def cpf_pattern(cpf):
pattern = r"^(\d{3}.){2}\d{3}-\d{2}$"
return bool(re.match(pattern, cpf))
Utilizei a conversão para booleano (bool) porque o método match não retorna simplesmente True ou False. Caso a string contendo o padrão especificado o método retorna um objeto da classe Match, que por si só possui outros métodos que não explorarei neste artigo.
Método re.findall(pattern, string, flags=0)
O método findall serve para retornar uma lista de ocorrências ou grupos de ocorrências de um padrão em uma string. Também precisa dos parâmetros pattern e string para rodar e novamente não abordarei o parâmetro flags para simplificar a abordagem.
Imagine que ao invés de validar o formato de um CPF você queira encontrar todos os CPFs contidos em uma string. Uma função poderia ser escrita da seguinte forma:
def get_cpfs(text):
pattern = r"\d{3}\.\d{3}\.\d{3}-\d{2}"
return re.findall(pattern, text)
Os mais observadores vão perceber a utilização de uma sintaxe diferente para descrever o mesmo padrão de string, no caso o CPF.
Não usei a notação de grupos de caracteres, separados por ( ), porque o método findall retorna uma lista de tuplas com os padrões referentes aos grupos separadamente, e nesse caso, queremos obter apenas a lista de CPFs.
Com esses métodos inúmeras abordagens para resolução de problemas cotidianos podem ser criadas, mas uma série de outros métodos são apresentados na documentação oficial da biblioteca.
Por que aprender Python ReGex?
As ideias apresentadas no artigo são básicas e envolvem um entendimento simples dos conceitos de Python ReGex, ou seja, de regex e da biblioteca re do python.
Mesmo assim, a gama de situações em que podem ser empregadas é imensa. Desde o tratamento simples de strings em um arquivo de texto, até o escaneamento de páginas web em busca de padrões de interesse.
Aprender a utilização de Python ReGex ou qualquer outra linguagem de programação acelera a resolução de problemas relacionados ao tratamento de strings ou textos.
Quer saber mais sobre o assunto? Deixe um comentário!
Você conhece a página de vagas da GeekHunter? Dá uma olhada nas oportunidades de emprego para desenvolvedores Python. Para demonstrar interesse em uma vaga é muito simples: basta criar um perfil (grátis) e ser aprovado(a) em nossos testes. Bora conferir?