Python
Expresiones Regulares
¿Que son?
Poderoso lenguaje para hacer coincidir patrones de texto
Con Python el módulo 're' es el que les da soporte
match = re.search(pat, str)
re.search()
- Si la búsqueda es exitosa, retorna un objeto
- Si no exitosa, retorna None
Patrones básicos
- a, X, 9, < -- caracteres ordinarios sólo coinciden con sí mismos de manera exacta. Los meta-caracteres que no coinciden con sigo mismos porque tienen un significado especial son:: . ^ $ * + ? { [ ] \ | ( )
- . (un punto) -- coincide cualquier caracter (1 sólo) excepto por la línea nueva '\n'
- \w -- (w minúscula) coincide un caracter de "palabra": es decir, una letra o dígito o guión bajo [a-zA-Z0-9_]. \W (W mayúscula) coincide cualquier caracter no-palabra.
- \b -- límite entre palabra y no palabra
Patrones básicos (cont)
- \s -- (s minúscula) coincide un solo caracter de espacio -- espacio, nueva línea, retorno, tab: [ \n\r\t\f]. \S (S mayúscula) coincide cuanquier caracter no-espacio.
- \t, \n, \r -- tab, nueva línea, retorno
- \d -- dígito decimal [0-9] (algunas utilidades viejas no lo soportan, pero todas soportan \w and \s)
- ^ = comienzo, $ = fin -- coinciden el comienzo o fin de una cadena.
- \ -- cancela lo "especial" de un caracter. Así, por ejemplo, utilizar \. para coincidir un punto.
Reglas
- La búsqueda ocurre a lo largo de la cadena, parando en la primer coincidencia.
- Todo el patrón debe coincidir, pero no en toda la cadena.
- Si match = re.search(pat, str) es exitoso, match no es None y el texto encontrado está en match.group()
Las reglas básicas de las expresiones regulares para buscar un patrón en una cadena son
Ejemplos básicos
Chiste: what do you call a pig with three eyes? piiig!
Repetición
- + -- 1 o más ocurrencias del patrón a su izquierda. Ej: 'i+' = una o más 'i'es
- * -- 0 o más ocurrencias del patrón a su izquierda
- ? -- 0 o 1 ocurrencias del patrón a su izquierda
Más a la izquierda y más grande
Primero encuentra la coincidencia de más a la izquierda del patrón, y segundo intenta usar todo lo que pueda de la cadena -- Ej. + y * abarcan lo más posible (el + y * son "codiciosos").
Ejemplo de repetición
Ejemplo con E-mail
Suponiendo que queremos encontrar la dirección de correo dentro de la cadena 'xyz alice-b@google.com mono violeta'
Notar que la búsqueda no devuelve todo el email porque \w no encuentra '-' o '.'
Corchetes
- Indican un grupo de caracteres
- [abc] conciden 'a', 'b' o 'c'
- \w, \s etc. funcionan dentro de los corchetes
- El punto (.) no funciona en los corchetes, significa solamente punto literal.
- Se puede usar el guión para indicar un rango: [a-z] encuentra todas las minúsculas.
- Para buscar guiones, colocarlo al final: [abc-].
- Un acento circumflejo al comienzo de corchetes busca el inverso: [^ab] busca cualquier caracter menos a o b
Extracción de grupos
- Permite extraer partes de una búsqueda
- cada parte va entre paréntesis
- Los paréntesis no cambian el patrón de búsqueda
- match.group(1) el la coincidencia en el primer paréntesis
- match.group() sigue devolviendo la coincidencia completa
findall
Encuentra todas las ocurrencias del patrón
En archivos
# Open file
f = open('test.txt', 'r')
# Alimenta el archivo de texto en findall(); retorna una
# lista de todas las cadenas encontradas
strings = re.findall(r'algun patron', f.read())
findall y Grupos
- El mecanismo de paréntesis de grupos se puede combinar con findall
- Si hay 2 o más paréntesis, el valor retornado es una lista de tuplas
Flujo de trabajo y depuración
- Los patrones de expresiones regulares empaquetan mucho significado en unos pocos caracteres
- Si el patrón no encuentra nada, hacerlo más débil quitándole partes.
- Una vez que se obtienen muchos resultados, ajustarlo incrementalmente hasta lograr lo que se quería.
- Herramientas en línea: http://www.regexr.com/ http://regex101.com/
Opciones
- IGNORECASE -- ignora las diferencias entre mayúsculas y minúsculas.
- DOTALL -- permite que el punto (.) coincida con una nueva línea -- normalmente coincide con cualquier cosa menos una nueva línea (aunque es mejor usar \s* para esto).
- MULTILINE -- Permite que ^ and $ coincidan con el comienzo y fin de cada línea. Normalmente ^/$ sólo coinciden con el inicio y fin de toda la cadena.
Las funciones de re aceptan opciones para modificar su comportamiento, la opción se agrega como un argumento extra a search() o findall() ,ej: re.search(pat, str, re.IGNORECASE)
Codicioso y no-codicioso
- Ejemplo de cadena: <b>foo</b> y <i>asi vamos</i>
- Nuestro patrón: (<.*>)
- Probar!
- El aspecto codicioso de .* Provoca que coincida con toda la cadena.
- Recordar que .* va todo lo lejos que puede en vez de frenar en la primer coincidencia! > codicioso
- Se puede agregar un ? para hacerlo no-codicioso
- Si hacemos (<.*?>), devuelve <b>, </b>, etc.
- ? es una extensión, no todos los engines lo reconocen
- los corchetes [] con ^ combinados excluyen el patron dentro de la búsqueda. Probar [^>]*
Substitución
- re.sub(patron, reempazo, cadena) busca todas las coincidencias de cadena, y las reemplaza
- La cadena de reemplazo puede incluir '\1', '\2' que se refieren a group(1), group(2), etc del patrón original
import re
str = 'xyz alice-b@google.com mono violeta bob@abc.com bla lavaplatos'
## re.sub(patron, reemplazo, cadena) -- retorna una nueva cadena con
## todo reemplazado, \1 es group(1), \2 group(2) en el reemplazo
print re.sub(r'([\w\.-]+)@([\w\.-]+)', r'\1@yo-yo-dyne.com', str)
Material de lectura extra
python-expresiones-regulares
By Guillermo Nuñez
python-expresiones-regulares
- 3,102