Expressões Regulares
Uma expressão regular (abreviada como regex [...]) é uma sequência de caracteres que especifica um padrão de busca em texto. [...] usada por algoritmos de busca de strings para operações de "localizar" ou "localizar e substituir" em strings, ou para validação de entrada.
- Importe o módulo regex com
import re. - Crie um objeto Regex com a função
re.compile(). (Lembre-se de usar uma string bruta/raw string.) - Passe a string que você deseja pesquisar para o método
search()do objeto Regex. Isso retorna um objetoMatch. - Chame o método
group()do objeto Match para retornar uma string do texto realmente correspondido.
Todas as funções regex em Python estão no módulo re:
# Importa o módulo re para operações de expressão regular
import re
Símbolos Regex
| Símbolo | Corresponde a |
|---|---|
? | zero ou uma ocorrência do grupo precedente. |
* | zero ou mais ocorrências do grupo precedente. |
+ | uma ou mais ocorrências do grupo precedente. |
{n} | exatamente n ocorrências do grupo precedente. |
{n,} | n ou mais ocorrências do grupo precedente. |
{,m} | 0 a m ocorrências do grupo precedente. |
{n,m} | no mínimo n e no máximo m ocorrências do p precedente. |
{n,m}? ou *? ou +? | executa uma correspondência não-gulosa (non-greedy) do p precedente. |
^spam | significa que a string deve começar com spam. |
spam$ | significa que a string deve terminar com spam. |
. | qualquer caractere, exceto caracteres de nova linha. |
\d, \w, e \s | um dígito, palavra, ou caractere de espaço, respectivamente. |
\D, \W, e \S | qualquer coisa exceto um dígito, palavra, ou espaço, respectivamente. |
[abc] | qualquer caractere entre os colchetes (como a, b, ). |
[^abc] | qualquer caractere que não esteja entre os colchetes. |
Objetos de correspondência Regex
# re.compile(): cria o objeto de padrão regex (use string bruta r'' para evitar escape)
phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # Padrão: 3 dígitos-3 dígitos-4 dígitos
mo = phone_num_regex.search('My number is 415-555-4242.') # Procura pelo padrão
print(f'Phone number found: {mo.group()}') # group() retorna o texto correspondido
Phone number found: 415-555-4242
Agrupamento com parênteses
# Parênteses criam grupos: group(1) retorna o primeiro grupo, group(2) retorna o segundo
phone_num_regex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') # Dois grupos entre parênteses
mo = phone_num_regex.search('My number is 415-555-4242.')
mo.group(1) # Retorna o primeiro grupo: '415'
'415'
mo.group(2)
'555-4242'
mo.group(0)
'415-555-4242'
mo.group()
'415-555-4242'
Faça login para responder este quiz e acompanhar seu progresso de aprendizagem
group() retorna quando chamado em um objeto de correspondência?Para recuperar todos os grupos de uma vez, use o método groups():
# groups(): retorna uma tupla de todos os grupos
mo.groups() # Retorna ('415', '555-4242')
('415', '555-4242')
area_code, main_number = mo.groups()
print(area_code)
415
print(main_number)
555-4242
Múltiplos grupos com Pipe
Você pode usar o caractere | onde quiser corresponder a uma de muitas expressões.
hero_regex = re.compile (r'Batman|Tina Fey')
mo1 = hero_regex.search('Batman and Tina Fey.')
mo1.group()
'Batman'
mo2 = hero_regex.search('Tina Fey and Batman.')
mo2.group()
'Tina Fey'
Você também pode usar o pipe para corresponder a um de vários padrões como parte do seu regex:
bat_regex = re.compile(r'Bat(man|mobile|copter|bat)')
mo = bat_regex.search('Batmobile lost a wheel')
mo.group()
'Batmobile'
mo.group(1)
'mobile'
Correspondência opcional com o Ponto de Interrogação
O caractere ? sinaliza o grupo que o precede como uma parte opcional do padrão.
bat_regex = re.compile(r'Bat(wo)?man')
mo1 = bat_regex.search('The Adventures of Batman')
mo1.group()
'Batman'
mo2 = bat_regex.search('The Adventures of Batwoman')
mo2.group()
'Batwoman'
Correspondência de zero ou mais com o Asterisco
O * (asterisco) significa “corresponder zero ou mais”. O grupo que precede o asterisco pode ocorrer qualquer número de vezes no texto.
bat_regex = re.compile(r'Bat(wo)*man')
mo1 = bat_regex.search('The Adventures of Batman')
mo1.group()
'Batman'
mo2 = bat_regex.search('The Adventures of Batwoman')
mo2.group()
'Batwoman'
mo3 = bat_regex.search('The Adventures of Batwowowowoman')
mo3.group()
'Batwowowowoman'
Correspondência de um ou mais com o Mais
O + (ou mais) significa corresponder um ou mais. O grupo que precede um mais deve aparecer pelo menos uma vez:
bat_regex = re.compile(r'Bat(wo)+man')
mo1 = bat_regex.search('The Adventures of Batwoman')
mo1.group()
'Batwoman'
mo2 = bat_regex.search('The Adventures of Batwowowowoman')
mo2.group()
'Batwowowowoman'
mo3 = bat_regex.search('The Adventures of Batman')
mo3 is None
True
Correspondência de repetições específicas com Chaves
Se você tem um grupo que deseja repetir um número específico de vezes, siga o grupo no seu regex com um número entre chaves:
ha_regex = re.compile(r'(Ha){3}')
mo1 = ha_regex.search('HaHaHa')
mo1.group()
'HaHaHa'
mo2 = ha_regex.search('Ha')
mo2 is None
True
Em vez de um número, você pode especificar um intervalo com um mínimo e um máximo entre as chaves. Por exemplo, o regex (Ha){3,5} corresponderá a ‘HaHaHa’, ‘HaHaHaHa’ e ‘HaHaHaHaHa’.
ha_regex = re.compile(r'(Ha){2,3}')
mo1 = ha_regex.search('HaHaHaHa')
mo1.group()
'HaHaHa'
Correspondência gulosa (Greedy) e não-gulosa (Non-greedy)
As expressões regulares do Python são gulosas (greedy) por padrão: em situações ambíguas, elas corresponderão à string mais longa possível. A versão não-gulosa das chaves, que corresponde à string mais curta possível, tem a chave de fechamento seguida por um ponto de interrogação.
greedy_ha_regex = re.compile(r'(Ha){3,5}')
mo1 = greedy_ha_regex.search('HaHaHaHaHa')
mo1.group()
'HaHaHaHaHa'
non_greedy_ha_regex = re.compile(r'(Ha){3,5}?')
mo2 = non_greedy_ha_regex.search('HaHaHaHaHa')
mo2.group()
'HaHaHa'
Faça login para responder este quiz e acompanhar seu progresso de aprendizagem
_ em vez de +? após o quantificador (ex: _?, +?, {3,5}?)O método findall()
O método findall() retornará as strings de cada correspondência na string pesquisada.
phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # não tem grupos
phone_num_regex.findall('Cell: 415-555-9999 Work: 212-555-0000')
['415-555-9999', '212-555-0000']
Criando suas próprias classes de caracteres
Você pode definir sua própria classe de caracteres usando colchetes. Por exemplo, a classe de caracteres [aeiouAEIOU] corresponderá a qualquer vogal, minúscula ou maiúscula.
vowel_regex = re.compile(r'[aeiouAEIOU]')
vowel_regex.findall('Robocop eats baby food. BABY FOOD.')
['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']
Você também pode incluir intervalos de letras ou números usando um hífen. Por exemplo, a classe de caracteres [a-zA-Z0-9] corresponderá a todas as letras minúsculas, letras maiúsculas e números.
Ao colocar um acento circunflexo (^) logo após o colchete de abertura da classe de caracteres, você pode criar uma classe de caracteres negativa que corresponderá a todos os caracteres que não estão na classe de caracteres:
consonant_regex = re.compile(r'[^aeiouAEIOU]')
consonant_regex.findall('Robocop eats baby food. BABY FOOD.')
['R', 'b', 'c', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.']
Os caracteres Caret e Dollar sign
Você também pode usar o símbolo de acento circunflexo
^no início de um regex para indicar que uma correspondência deve ocorrer no início do texto pesquisado.Da mesma forma, você pode colocar um cifrão
$no final do regex para indicar que a string deve terminar com este padrão regex.E você pode usar o
^e o$juntos para indicar que a string inteira deve corresponder ao regex.
A string de expressão regular r'^Hello' corresponde a strings que começam com ‘Hello’:
begins_with_hello = re.compile(r'^Hello')
begins_with_hello.search('Hello world!')
<_sre.SRE_Match object; span=(0, 5), match='Hello'>
begins_with_hello.search('He said hello.') is None
True
A string de expressão regular r'\d\$' corresponde a strings que terminam com um caractere numérico de 0 a 9:
whole_string_is_num = re.compile(r'^\d+$')
whole_string_is_num.search('1234567890')
<_sre.SRE_Match object; span=(0, 10), match='1234567890'>
whole_string_is_num.search('12345xyz67890') is None
True
whole_string_is_num.search('12 34567890') is None
True
O caractere curinga (Wildcard)
O caractere . (ou ponto) em uma expressão regular corresponderá a qualquer caractere, exceto uma nova linha:
at_regex = re.compile(r'.at')
at_regex.findall('The cat in the hat sat on the flat mat.')
['cat', 'hat', 'sat', 'lat', 'mat']
Correspondendo tudo com Ponto-Asterisco
name_regex = re.compile(r'First Name: (.*) Last Name: (.*)')
mo = name_regex.search('First Name: Al Last Name: Sweigart')
mo.group(1)
'Al'
mo.group(2)
'Sweigart'
O .* usa modo guloso: Ele sempre tentará corresponder o máximo de texto possível. Para corresponder a qualquer texto de forma não-gulosa, use o ponto, asterisco e ponto de interrogação (.*?). O ponto de interrogação diz ao Python para corresponder de forma não-gulosa:
non_greedy_regex = re.compile(r'<.*?>')
mo = non_greedy_regex.search('<To serve man> for dinner.>')
mo.group()
'<To serve man>'
greedy_regex = re.compile(r'<.*>')
mo = greedy_regex.search('<To serve man> for dinner.>')
mo.group()
'<To serve man> for dinner.>'
Correspondendo novas linhas com o caractere Ponto
O ponto-asterisco corresponde a tudo, exceto uma nova linha. Ao passar re.DOTALL como o segundo argumento para re.compile(), você pode fazer com que o caractere ponto corresponda a todos os caracteres, incluindo o caractere de nova linha:
no_newline_regex = re.compile('.*')
no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
'Serve the public trust.'
newline_regex = re.compile('.*', re.DOTALL)
newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
Correspondência sem distinção entre maiúsculas e minúsculas (Case-Insensitive)
Para tornar seu regex insensível a maiúsculas e minúsculas, você pode passar re.IGNORECASE ou re.I como segundo argumento para re.compile():
robocop = re.compile(r'robocop', re.I)
robocop.search('Robocop is part man, part machine, all cop.').group()
'Robocop'
robocop.search('ROBOCOP protects the innocent.').group()
'ROBOCOP'
robocop.search('Al, why does your programming book talk about robocop so much?').group()
'robocop'
Substituindo strings com o método sub()
O método sub() para objetos Regex recebe dois argumentos:
- O primeiro argumento é uma string para substituir quaisquer correspondências.
- O segundo é a string para a expressão regular.
O método sub() retorna uma string com as substituições aplicadas:
names_regex = re.compile(r'Agent \w+')
names_regex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.')
'CENSORED gave the secret documents to CENSORED.'
Faça login para responder este quiz e acompanhar seu progresso de aprendizagem
sub() faz?Gerenciando Regexes complexos
Para instruir a função re.compile() a ignorar espaços em branco e comentários dentro da string de expressão regular, o “modo verboso” pode ser ativado passando a variável re.VERBOSE como o segundo argumento para re.compile().
Agora, em vez de uma expressão regular difícil de ler como esta:
phone_regex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)')
você pode espalhar a expressão regular por várias linhas com comentários como este:
phone_regex = re.compile(r'''(
(\d{3}|\(\d{3}\))? # código de área
(\s|-|\.)? # separador
\d{3} # primeiros 3 dígitos
(\s|-|\.) # separador
\d{4} # últimos 4 dígitos
(\s*(ext|x|ext.)\s*\d{2,5})? # extensão
)''', re.VERBOSE)
Faça login para responder este quiz e acompanhar seu progresso de aprendizagem
re.VERBOSE faz quando passado para re.compile()?