Técnicas avanzadas de grupos de captura (Advanced Capture Group Techniques)
Más allá de los grupos de captura básicos, las expresiones regulares (regex) de Python ofrecen características más avanzadas como grupos de captura anidados, grupos sin captura y lookarounds (inspecciones hacia adelante/atrás).
Grupos de captura anidados (Nested Capture Groups)
Los grupos de captura se pueden anidar dentro de otros grupos de captura para extraer información más granular.
Cree un nuevo archivo llamado nested_capture.py en el directorio ~/project.
touch ~/project/nested_capture.py
Abra nested_capture.py y agregue el siguiente 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.")
Guarde el archivo.
Ejecute el script.
python ~/project/nested_capture.py
La salida mostrará los datos extraídos, incluido el nombre completo y sus componentes:
Full Name: John Doe
First Name: John
Last Name: Doe
ID: 12345
Aquí, ((\w+)\s(\w+)) es un grupo de captura anidado. group(1) captura el "John Doe" completo, group(2) captura "John" y group(3) captura "Doe". group(4) captura el ID.
Grupos sin captura (Non-Capturing Groups)
A veces, necesita agrupar partes de un patrón para aplicar cuantificadores o alternativas, pero no necesita capturar el contenido. Los grupos sin captura (?:...) se utilizan para este propósito.
Cree un nuevo archivo llamado non_capturing.py en el directorio ~/project.
touch ~/project/non_capturing.py
Abra non_capturing.py y agregue el siguiente 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}")
Guarde el archivo.
Ejecute el script.
python ~/project/non_capturing.py
La salida mostrará los nombres de dominio extraídos:
Domain from 'https://www.example.com/path': example.com
Domain from 'http://example.org/another/path': example.org
En este ejemplo, (?:www\.)? coincide con "www." si existe, pero no lo captura, por lo que group(1) captura directamente el nombre de dominio.
El uso de grupos sin captura puede mejorar ligeramente el rendimiento y mantiene los índices de los grupos capturados más limpios cuando solo necesita capturar partes específicas de un patrón más grande.