Técnicas Avançadas de Grupos de Captura
Além dos grupos de captura básicos, as expressões regulares (regex) em Python oferecem recursos mais avançados, como grupos de captura aninhados, grupos não capturantes e lookarounds.
Grupos de Captura Aninhados
Grupos de captura podem ser aninhados dentro de outros grupos de captura para extrair informações mais granulares.
Crie um novo arquivo chamado nested_capture.py no diretório ~/project.
touch ~/project/nested_capture.py
Abra nested_capture.py e adicione o seguinte código:
import re
def parse_complex_data(text):
pattern = r'((\w+)\s(\w+))\s\[(\d+)\]'
match = re.match(pattern, text)
if match:
full_name = match.group(1)
first_name = match.group(2)
last_name = match.group(3)
id_number = match.group(4)
return {
'full_name': full_name,
'first_name': first_name,
'last_name': last_name,
'id': id_number
}
return None
text = 'John Doe [12345]'
result = parse_complex_data(text)
if result:
print(f"Full Name: {result['full_name']}")
print(f"First Name: {result['first_name']}")
print(f"Last Name: {result['last_name']}")
print(f"ID: {result['id']}")
else:
print("No match found.")
Salve o arquivo.
Execute o script.
python ~/project/nested_capture.py
A saída mostrará os dados extraídos, incluindo o nome completo e seus componentes:
Full Name: John Doe
First Name: John
Last Name: Doe
ID: 12345
Aqui, ((\w+)\s(\w+)) é um grupo de captura aninhado. group(1) captura todo o "John Doe", group(2) captura "John" e group(3) captura "Doe". group(4) captura o ID.
Grupos Não Capturantes
Às vezes, você precisa agrupar partes de um padrão para aplicar quantificadores ou alternativas, mas não precisa capturar o conteúdo. Grupos não capturantes (?:...) são usados para essa finalidade.
Crie um novo arquivo chamado non_capturing.py no diretório ~/project.
touch ~/project/non_capturing.py
Abra non_capturing.py e adicione o seguinte código:
import re
def extract_domain_info(url):
## (?:) creates a non-capturing group
pattern = r'https?://(?:www\.)?([^/]+)'
match = re.match(pattern, url)
if match:
domain = match.group(1) ## Only the domain is captured
return domain
return None
url1 = 'https://www.example.com/path'
domain1 = extract_domain_info(url1)
print(f"Domain from '{url1}': {domain1}")
url2 = 'http://example.org/another/path'
domain2 = extract_domain_info(url2)
print(f"Domain from '{url2}': {domain2}")
Salve o arquivo.
Execute o script.
python ~/project/non_capturing.py
A saída mostrará os nomes de domínio extraídos:
Domain from 'https://www.example.com/path': example.com
Domain from 'http://example.org/another/path': example.org
Neste exemplo, (?:www\.)? corresponde a "www." se existir, mas não o captura, então group(1) captura diretamente o nome do domínio.
Usar grupos não capturantes pode melhorar ligeiramente o desempenho e mantém os índices de grupo capturados mais limpos quando você só precisa capturar partes específicas de um padrão maior.