0% encontró este documento útil (0 votos)
4 vistas60 páginas

Programación Avanzada en Python

El documento aborda temas avanzados de programación en Python, incluyendo el acceso a variables de entorno, el uso de módulos, la creación de entornos virtuales y la implementación de bots en Telegram. Se presentan ejemplos prácticos y se discuten buenas prácticas en la gestión de módulos y opciones de línea de comandos. Además, se introduce la librería 'telepot' para interactuar con la API de Telegram.

Cargado por

Rose Loiz
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
4 vistas60 páginas

Programación Avanzada en Python

El documento aborda temas avanzados de programación en Python, incluyendo el acceso a variables de entorno, el uso de módulos, la creación de entornos virtuales y la implementación de bots en Telegram. Se presentan ejemplos prácticos y se discuten buenas prácticas en la gestión de módulos y opciones de línea de comandos. Además, se introduce la librería 'telepot' para interactuar con la API de Telegram.

Cargado por

Rose Loiz
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Programación en Python (II)

Miguel Ortuño
Escuela de Ingenierı́a de Fuenlabrada
Universidad Rey Juan Carlos

Diciembre de 2024

URJC - EIF - 2024 Programación en Python (II) 1


© 2023 Miguel Angel Ortuño Pérez.
Algunos derechos reservados. Este documento se distribuye bajo la
licencia Atribución-CompartirIgual 4.0 Internacional de Creative
Commons, disponible en
[Link]

URJC - EIF - 2024 Programación en Python (II) 2


Contenidos

Acceso a las variables de entorno


Módulos
optparse
Entornos virtuales
Bots de telegram
Creación de un bot de telegram
Uso de la librerı́a telepot
Expresiones Regulares en python
Introducción
Metacaracteres
Regexp en python

URJC - EIF - 2024 Programación en Python (II) 3


Acceso a las variables de entorno

Variables de entorno

#!/usr/bin/env python3
# [Link]
import os, sys
mi_variable=[Link]("MI_VARIABLE")
if mi_variable==None:
msg="ERROR: variable de entorno MI_VARIABLE no definida"
[Link](msg+'\n')
raise SystemExit

Atención: Cuando la shell crea un proceso (p.e. el intérprete de


python), puede no pasarle todas las variables de entorno. Por
tanto, las variables visibles desde la shell serán distintas a las
visibles desde python

URJC - EIF - 2024 Programación en Python (II) 4


Módulos

Módulos
Un módulo es un fichero que contiene definiciones y sentencias,
que pueden ser usados desde otro fichero
mi [Link]

#!/usr/bin/env python3
a=3
def f(x):
return x+1

[Link]

#!/usr/bin/env python3
import mi_modulo

print(mi_modulo.a) # 3
print(mi_modulo.f(0)) # 1

URJC - EIF - 2024 Programación en Python (II) 5


Módulos

También se pueden importar los objetos por separado, de forma


que luego se puede usar sin indicar explı́citamente el módulo

#!/usr/bin/env python3
from mi_modulo import f
from mi_modulo import a

print(f(0)) # 1
print(a) # 3

URJC - EIF - 2024 Programación en Python (II) 6


Módulos

Es posible importar todos los objetos de un módulo

#!/usr/bin/env python3
from mi_modulo import *

print(f(0)) # 1
print(a) # 3

Pero esto es una mala práctica, porque cuando el número de


módulos aumenta, es difı́cil saber en qué módulo está cada objeto

URJC - EIF - 2024 Programación en Python (II) 7


Módulos

Búsqueda de los módulos

El intérprete busca los módulos en el siguiente orden


1 En el directorio del script
2 En cada directorio indicado en la variable de entorno
PYTHONPATH
3 En el directorio por omisión
En Unix y Linux suele estar en /usr/lib
Por ejemplo
/usr/lib/python3.9

URJC - EIF - 2024 Programación en Python (II) 8


Módulos

Ficheros .pyc

Cuando se importa un módulo, si el intérprete tiene permisos,


guarda en el mismo directorio un fichero con extensión .pyc que
contiene el script compilado en bytecodes
Este fichero ahorra tiempo la segunda vez que se ejecuta el
módulo
No es dependiente de la arquitectura pero sı́ de la versión
exacta del intérprete. Si no existe o no es adecuado, se genera
uno nuevo automáticamente
Permite borrar el fuente .py si no queremos distribuirlo

URJC - EIF - 2024 Programación en Python (II) 9


Módulos

Objetos en módulos

Usar objetos globales es peligroso, muchas metodologı́as lo


prohı́ben
Pero usar algún objeto global, en un módulo compartido por
otros módulos, en algunas ocasiones puede ser una práctica
aceptable y conveniente

URJC - EIF - 2024 Programación en Python (II) 10


Módulos

mis [Link]

#!/usr/bin/env python3
a=3

[Link]

#!/usr/bin/env python3
import mis_globales
def f():
return mis_globales.a

[Link]

#!/usr/bin/env python3
import mis_globales, modulo1

print(modulo1.f()) #3
mis_globales.a=5
print(modulo1.f()) #5

URJC - EIF - 2024 Programación en Python (II) 11


Módulos

Un fichero puede ser un script y un módulo simultáneamente, si


añadimos una función main() y la sentencia

if __name__== "__main__":
main()

De esta manera,
Si el fichero se ejecuta como un script, el intérprete ejecutará
la función main()
Si el fichero se usa como módulo, importando sus funciones
desde otro script, la función main() no será ejecutada

URJC - EIF - 2024 Programación en Python (II) 12


Módulos

[Link]

#!/usr/bin/env python3
def f(x):
return x+1

def main():
print("probando f", f(2))

if __name__== "__main__":
main()

[Link]

#!/usr/bin/env python3
import modulo1
print(modulo1.f(0)) #1 No se ejecuta main()

URJC - EIF - 2024 Programación en Python (II) 13


optparse

optparse

optparse es una librerı́a de python para procesar las opciones y


argumentos con los que se llama a un script
orden opciones argumentos
-------------------------------------------------
cp -r -v directorio1 directorio2

En un buen interfaz
Las opciones deben ser opcionales. (El programa debe hacer
algo útil sin ninguna opción)
Las opciones proporcionan flexibilidad, pero demasiadas
introducen complejidad
Los parámetros fundamentales e imprescindibles deben ser
argumentos

URJC - EIF - 2024 Programación en Python (II) 14


optparse

Creamos una instancia de la clase OptionParser, pasando


como argumento la cadena usage (que se mostrará al usuario
cuando use mal el script, o cuando lo llame con -h o --help

usage = "Uso: %prog [opciones] origen destino"


parser = OptionParser(usage)

Para añadir opciones invocamos al método add_option

parser.add_option("-v", "--verbose",
action="store_true", dest="verbose",
help="Informe detallado")

Invocamos a parse_args(), que devuelve las opciones ya


procesadas y los argumentos

opciones, argumentos = parser.parse_args()

URJC - EIF - 2024 Programación en Python (II) 15


optparse

#!/usr/bin/env python3
# [Link]
import sys

from optparse import OptionParser


def main():
usage = "%prog [opciones] origen destino"
parser = OptionParser(usage)
parser.add_option("-e", "--energy",
action="store", dest="energy",
help="Tipo de energia a usar en la copia ",
default='eolic')
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose",
help="Informe detallado")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose",
help="Informe silencioso")
opciones, argumentos = parser.parse_args()

URJC - EIF - 2024 Programación en Python (II) 16


optparse

if len(argumentos) != 2:
[Link]("Número incorrecto de argumentos")
print("Tipo de energia:"+[Link])
print("Origen:",argumentos[0])
print("Destino:",argumentos[1])
if [Link]:
print("mucho blablabla ")

if __name__ == "__main__":
main()

URJC - EIF - 2024 Programación en Python (II) 17


optparse

add option

parser.add_option("-e", "--energy",
action="store", dest="energy",
help="Tipo de energia a usar en la copia ", default='eolic')

Cada opción puede invocarse con una única letra (p.e. -v) o
con una palabra (p.e. --verbose)
Con el atributo help se construye el mensaje que se mostrará
al usuario cuando invoque el programa con -h o --help
La opción puede
Limitarse a activar o desactivar un flag.
action="store_true" action="store_false"
Indicar un valor
action="store"
En ambos casos, la información se almacena en un atributo
que se llama como indique el parámetro dest
URJC - EIF - 2024 Programación en Python (II) 18
optparse

parser.add_option("-d", "--discount",
action="store", dest="discount", type="float",
help="Coeficiente de descuento")

Por omisión el tipo de la opción es un string, pero también


acepta string, int, long, choice, float y complex

URJC - EIF - 2024 Programación en Python (II) 19


optparse

koji@mazinger:~/python$ ./cp_ecologico.py
Usage: cp_ecologico.py [opciones] origen destino

cp_ecologico.py: error: Número incorrecto de argumentos

koji@mazinger:~/python$ ./cp_ecologico.py -h
Usage: cp_ecologico.py [opciones] origen destino

Options:
-h, --help show this help message and exit
-e ENERGY, --energy=ENERGY
Tipo de energia a usar en la copia
-v, --verbose Informe detallado
-q, --quiet Informe silencioso
-d DISCOUNT, --discount=DISCOUNT
Coeficiente de descuento

koji@mazinger:~/python$ ./cp_ecologico.py -v -d 0.15 mi_origen mi_destino


Tipo de energia:eolic
Coeficiente de descuento:0.15
Origen: mi_origen
Destino: mi_destino
mucho blablabla

URJC - EIF - 2024 Programación en Python (II) 20


Entornos virtuales

Entornos virtuales

Un entorno virtual es una herramienta que permite crear un espacio


aislado para instalar y gestionar paquetes de Python. Es útil para:
Evitar conflictos entre dependencias de diferentes proyectos.
Reproducir entornos fácilmente en diferentes máquinas.
Mantener el sistema global limpio.

URJC - EIF - 2024 Programación en Python (II) 21


Entornos virtuales

Creación de un entorno virtual

python3 -m venv env


Esto genera una carpeta llamada env que contiene un
intérprete de Python y un entorno para instalar paquetes. De
esta forma, todas las librerı́as que necesite el programa se
leerán de esta carpeta, no de ninguna carpeta global
Podrı́amos usar cualquier otro nombre, pero env es el
tradicional

URJC - EIF - 2024 Programación en Python (II) 22


Entornos virtuales

Activar el entorno virtual

source env/bin/activate
Cambia el intérprete de Python al del entorno virtual.
Usa todas las librerı́as del entorno virtual
Verás el nombre del entorno (env) en el prompt del terminal,
indicando que estás dentro del entorno.
deactivate
Desactiva el entorno, vuelve al intérprete de Python global

URJC - EIF - 2024 Programación en Python (II) 23


Bots de telegram

Bots de telegram

Telegram es una aplicación de mensajerı́a instantánea muy similar


a WhatsApp, con la que tiene las siguientes diferencias:
Telegram es muy popular pero no tiene tantos usuarios como
WhatsApp
Telegram no solo tiene clientes para iOS y Android (como
WhatsApp) , también tiene clientes independientes del
telefono para Windows, Linux y macOS
El cliente es software libre (el servidor,no)
Fácilmente accesible mediante API
En python hay muchas librerı́as para manejar telegram, aquı́
veremos telepot

URJC - EIF - 2024 Programación en Python (II) 24


Bots de telegram

Para poder enviar y recibir mensajes, hay que crear un tipo de


usuario especial llamado bot
Para crear un bot, tenemos que usar otro bot, llamado BotFather
1 Desde nuestro cliente de telegram, enviamos un mensaje con
el texto /newbot al usuario @BotFather
2 Un diálogo nos irá preguntando todo lo necesario
3 Recibiremos un token que nos permitirá maneja el bot via API
De la misma forma, @BotFather nos permite cambiar el nombre
de nuestro bot (comando /newbot), su foto (/setuserpic),
eliminarlo (deletebot), etc

URJC - EIF - 2024 Programación en Python (II) 25


Bots de telegram

Para que un bot de telegram pueda enviar un mensaje a un


usuario, hace falta:
1 Que el usuario le envı́e al bot un mensaje cualquiera (un
mensaje en la vida es suficiente)
2 Que el usuario facilite al programador del bot su propio id de
usuario
Es un número de unos 9 dı́gitos, no confundir con el nombre
de usuario (p.e. @JuanPerez)
El usuario puede averiguar su propio id enviando un mensaje
cualquiera al bot @userinfobot

URJC - EIF - 2024 Programación en Python (II) 26


Bots de telegram

Uso de la librerı́a telepot

Para instalar telepot


Si tenemos privilegios de root y queremos instalarlo para
todos los usuarios del sistema, ejecutamos desde la shell
sudo pip3 install telepot

En otro caso, podemos instalarlo solo para nuestro usuario


dentro de un entorno virtual
cd DIRECTORIO_DEL_PROYECTO
python3 -m venv env # Solo una vez
pip3 install telepot

cd DIRECTORIO_DEL_PROYECTO
python3 -m venv env # En cada ejecución

URJC - EIF - 2024 Programación en Python (II) 27


Bots de telegram

Enviar un mensaje a un usuario

#!/usr/bin/env python3

import telepot

TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
bot = [Link](TOKEN)

def main():
id_usuario = "999999999"
[Link](id_usuario, "Hola")

return

if __name__ == "__main__":
main()

El tamaño máximo del mensaje es 4096 caracteres

URJC - EIF - 2024 Programación en Python (II) 28


Bots de telegram

Contestar a los mensajes de un usuario

#!/usr/bin/env python3
import telepot
import [Link]
import time
from [Link] import MessageLoop

TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
bot = [Link](TOKEN)

def handle(msg):

chat_id = msg["chat"]["id"]
texto = msg["text"]

print("Recibiendo mensaje:")
print(msg)

respuesta = "Me has dicho " + texto


[Link](chat_id, respuesta)
return

URJC - EIF - 2024 Programación en Python (II) 29


Bots de telegram

def main():
MessageLoop(bot, handle).run_as_thread()
print "Escuchando..."

while 1:
[Link](10)
return

if __name__ == "__main__":
main()

Ejemplo:
Escuchando...
Recibiendo mensaje:
{u'date': 1542706429, u'text': u'Hola', u'from': {u'username': u'Juan_perez',
u'first_name': u'Juan', u'last_name': u'Perez', u'is_bot': False,
u'language_code': u'es', u'id': 154195197}, u'message_id': 2704, u'chat':
{u'username': u'Juan_perez', u'first_name': u'Juan', u'last_name': u'Perez',
u'type': u'private', u'id': 154196127}}

URJC - EIF - 2024 Programación en Python (II) 30


Bots de telegram

En los ejemplos anteriores, para preparar un ejemplo mı́nimo


hemos escrito el token en el código fuente
Por motivos de seguridad, en cualquier programa que no sea
una prueba de concepto, el token (o cualquier otra contraseña
similar) deberı́a ir en un fichero aparte
Al leer el token desde un fichero, será necesario que suprimas
el salto de lı́nea final
Puedes usar el método strip(), que devuelve una copia de la
cadena eliminando tabuladores, espacios y saltos de lı́nea al
princio y al final de una cadena

>>> a = ' hola '


>>> [Link]()
'hola'

URJC - EIF - 2024 Programación en Python (II) 31


Expresiones Regulares en python

Expresiones regulares. Introducción

Las expresione regulares son expresiones que definen un


conjunto de cadenas de texto
Pertenecen a la disciplinas de teorı́a de autómatas y lenguajes
formales. Las bases las sienta Stephen Cole Kleene en la
década de 1950. Se desarrollan en los años 60 y se
popularizan en los años 80
Se denominan abreviadamente re, regex o regexp
También patrón
Las regex son una herramienta muy potente para procesar
texto automáticamente. Especialmente texto plano, no son
muy apropiadas para HTML o XML

URJC - EIF - 2024 Programación en Python (II) 32


Expresiones Regulares en python

Las regex pueden manejarse desde


Herramientas clásicas como grep, sed, awk
Editores de texto
Librerı́as para lenguajes de programación clásicos como C o
Pascal
Librerı́as nativas en cualquier lenguaje moderno: perl, python,
java, ruby, c#, etc
Entre las distintinas versiones hay similitudes y diferencias
Las regex tradicionales (grep, sed, awk) se parecen bastante
entre sı́.
Las regex modernas se parecen entre sı́. Son una derivación de
las tradicionales. Su uso resulta más sencillo
Es una materia que puede llegar a resultar bastante compleja,
conocerlas a fondo es difı́cil. Pero manejar sus fundamentos
resulta de gran utilidad para prácticamente cualquier
programador en cualquier entorno

URJC - EIF - 2024 Programación en Python (II) 33


Expresiones Regulares en python

Algunas definiciones

Decimos que una regex y una cadena de texto encajan o no


encajan. 1
Ejemplo. Patrón/regex

[Aa]na [Pp].rez

La cadena Ana Pérez encaja


También encajan las cadenas ana perez, ana pérez,
ana porez, Ana p~ Nrez, etc
La cadena ANA PEREZ no encaja

1
O también se corresponde, se ajusta a. En inglés, match
URJC - EIF - 2024 Programación en Python (II) 34
Expresiones Regulares en python

Decimos que un carácter 2

Se usa como literal si representa a ese carácter.


Se usa como metacarácter (o comodı́n) si tiene un significado
especial, si representa algo distinto al propio carácter
Ejemplo: el punto usado como literal, representa un punto.
Usado como metacarácter, representa cualquier carácter
Normalmente, cuando un carácter puede tomarse como
metacarácter o como literal
Por omisión se toma como metacarácter
Para interpretarlo como literal, hay que escaparlo. Tı́picamente
anteponiendo una barra invertida o incluyendolo entre comillas,
rectas o dobles. Ejemplo: \.

2
la palabra carácter es llana y lleva tilde, no es aguda. El plural es
caracteres, también es llana
URJC - EIF - 2024 Programación en Python (II) 35
Expresiones Regulares en python

Metacaracteres clásicos
^ Principio de cadena (principio de lı́nea)
$ Fin de cadena (fin de lı́nea)
. Cualquier carácter
* La regex precedente puede aparecer 0 o más veces
? La regex precedente puede aparecer o no aparecer
[] Clase de caracteres: uno cualquiera de los caracteres entre
corchetes
[^] Complementario de la clase de caracteres: cualquiera menos
los incluidos entre corchetes
[a-f] Caracteres de la 'a' hasta la 'f'
{2,3} La regex precedente se puede repetir entre 2 y 3 veces
{2,} La regex precedente se repite 2 o más veces
{,3} La regex precedente se repite entre 0 y 3 veces
{4} La regex precedente se repite 4 veces
() Permite agrupar una regex
\2 El segundo grupo de regex
r1|r2 Una regex u otra

\< Inicio de palabra


\> Fin de palabra
URJC - EIF - 2024 Programación en Python (II) 36
Expresiones Regulares en python

Ejemplos
[a-z][a-z0-9_]* letra minúscula seguida de cero o
más letras minúsculas, números o barras bajas
Se~
nora? Se~nor o Se~
nora
Serg[eé][iy]? Ra(j|ch|h|kh)m[aá]n[ij]no(v|ff|w)
Sergéi / Sergei / Sergey / Serge
Rajmáninov / Rachmaninoff / Rahmanjnov ...

Dentro una clase de caracteres, cada carácter siempre se toma


literalmente, no se escapa ningún posible metacarácter (excepto el
cierre de corchetes)
[0-9.] # Un dı́gito o un punto. (Aquı́ el punto representa
un punto, no "cualquier carácter")

Atención: algunos metacaracteres de bash coinciden, otros tienen


un significado distinto
? En bash, cualquier carácter
* En bash, cualquier carácter 0 o más veces

URJC - EIF - 2024 Programación en Python (II) 37


Expresiones Regulares en python

Fin de lı́nea
El fin de lı́nea se representa de diferentas maneras
En MS-DOS/Windows y otros, el fin de lı́nea se representa
con CRLF
En Unix, se representa con LF
Esto es una fuente tradicional de problemas
En Windows, un fichero para Unix se verá como una única
lı́nea
En Unix, un fichero para Windows tendrá un ^M al final de
cada lı́nea
Algunos editores son lo bastante listos como para mostrar
correctamente un fichero con un formato distinto
Pero ocultar el problema a veces es contraproducente: puede
suceder que la apariencia sea correcta, pero el compilador no
lo acepte y muestre un error muy confuso
URJC - EIF - 2024 Programación en Python (II) 38
Expresiones Regulares en python

Nombre ASCII Abreviatura Decimal Hexa Caret Notation Notación C


Carriage Return CR 13 OD ^M \r
Line Feed LF 10 0A ^J \n

Caret notation es una método empleado en ASCII para


representar caracteres no imprimibles. (Caret: acento
circunflejo). Normalmente, se puede usar la tecla control
para generar estos caracteres
Notación C: Notación del lenguaje C, que después han
seguido muchos otros como python
Obsérvese que nada de esto se refiere directamente a las
expresiones regulares: Cuando en una cadena escribimos \n, se
entiende que es un avance de lı́nea (excepto si lo escapamos con
otra barra adicional, o con una cadena cruda de python)
\n suele representar LF, excepto en macOS, donde suele representar CR.
En java o en .net sobre cualquier SO, siempre representa LF

URJC - EIF - 2024 Programación en Python (II) 39


Expresiones Regulares en python

Python emplea universal newlines:


En la E/S de ficheros, por omision:
Sea cual sea el criterio de la entrada, lo convierte a \n
A la salida, escribe el formato propio de la plataforma
Este comportamieto puede cambiarse si es necesario (consultar
PEP 278 y PEP 3116)
Para cadenas que no provengan de un fichero, se puede emplear el
método splitlines() de las cadenas, que:
Trocea una cadena con el mismo enfoque (soporta todos los
criterios), y elimina el fin de linea (sea el que sea)
A menos que se invoque splitlines(true), entonces conserve el
fin de linea, inalterado

URJC - EIF - 2024 Programación en Python (II) 40


Expresiones Regulares en python

Otra fuente tı́pica de problemas: ¿El fin de lı́nea es un terminador


o un separador?
Algunas herramientas/aplicaciones/sistemas operativos
entienden que es un separador, y por tanto la última lı́nea no
acaba en \n sino en fin de fichero
Otras consideran que es un terminador, por tanto la última
lı́nea sı́ acaba en \n (P.e. Unix)
Todo esto son cuestiones que puede ser necesario considerar
procesando texto. Pero si lo único que queremos es convertir
ficheros entre Windows y Unix, no hace falta usar regex
sed -e 's/$/\r/' inputfile > outputfile # Unix a Windows
sed -e 's/\r$//' inputfile > outputfile # Windows a Unix

El metacarácter $ de las regex no se corresponde exactamente con


CR ni con LF. Su significado exacto depende de la plataforma.
Normalmente encaja tanto con el fin de cadena como con la
posición inmediatamente antes de LF/CR/CRLF
URJC - EIF - 2024 Programación en Python (II) 41
Expresiones Regulares en python

Metacaracteres modernos

El lenguaje perl es el padre de las regex modernas. Incluye los


metacaracteres clásicos y añade otros nuevos. Lenguajes como
python copian las regex de perl
Metac. Clase equivalente
------------------------------------------------------------------
\d Dı́gito [0-9]
\s Espacio en blanco, tab... [\ \t\r\n\f] (*)
\w Carácter de palabra (alfanumético o barra baja) [0-9a-zA-Z_]
\D Cualquiera menos \d [^0-9]
\S Cualquiera menos \s [^\s]
\W Cualquiera menos \w; [^\w]
\b Limite de palabra. (Secuencia de alfanuméricos o barra baja)

(*) \t: Tab


\f: Form Feed, salto de página

URJC - EIF - 2024 Programación en Python (II) 42


Expresiones Regulares en python

Observaciones
El único metacarácter que cambia entre regex clásicas y
modernas es el lı́mite de palabra, se usa \b y no \< \>
Las locales no siembre están bien definidas, en tal caso para
definir una palabra tal vez haya que incluir explicitamente las
letras españolas (si procede)

URJC - EIF - 2024 Programación en Python (II) 43


Expresiones Regulares en python

Regexp en python

Para operaciones sencillas con cadenas, como búsquedas y


sustituciones sin metacaracteres, es más eficiente emplear los
métodos de las cadenas, como find y replace
El módulo re tiene funciones a la que se puede pasar
directamente una cadena regexp
>>> import re
>>> m=[Link]('[0-9]+' , 'abc98521zzz')
>>> [Link](0)
'98521'

Pero aquı́ usaremos objetos regex, más potentes

URJC - EIF - 2024 Programación en Python (II) 44


Expresiones Regulares en python

Regexp en python

Para usar regexp, importamos el módulo re


import re
Una regex es un objeto que construimos con la función
compile

regex=[Link]("a+")

Para buscar el patrón en una cadena tenemos los métodos


match(), que comprueba si el principio de la cadena encaja en
la regex
search(), que comprueba si alguna parte de la cadena encaja
en la regex
Ambos métodos devuelven
Un objeto SRE_Match si han tenido éxito (que se evalúa como
cierto)

URJC - EIF - 2024 Programación en Python (II) 45


Expresiones Regulares en python

#!/usr/bin/env python3
# [Link]
import re
regex=[Link]("aa+")

m=[Link]("taartamudo")
print(m) # None

m=[Link]("taartamudo")
print(m) # Cierto

m=[Link]("aaahora")
print(m) # Cierto

URJC - EIF - 2024 Programación en Python (II) 46


Expresiones Regulares en python

Casi siempre hay más de una regex posible. Ejemplo: Capturar una
dirección IP
Estas sentencias son equivalentes

direccion_ip=[Link](r"""\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?""")
direccion_ip=[Link](r"""(\d\d?\d?\.){3}\d\d?\d?""")
direccion_ip=[Link](r"""\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}""")
direccion_ip=[Link](r"""(\d{1,3}\.){3}\d{1,3}""")

Es necesario escapar el punto


Obsérvese que esta regex no se corresponde exactamente con
una dirección IP. Por ejemplo admitirı́a [Link]
Suele ser conveniente definir la regex con cadenas crudas de
python (r"""cadena""")
Esto evita tener que escapar las barras invertidas para que se
tomen como literales.
También permite, por ejemplo, que la secuencia \n se tome
como como una barra invertida y una ene. (Y no como un
salto de lı́nea carro)
URJC - EIF - 2024 Programación en Python (II) 47
Expresiones Regulares en python

Comentarios en las regex

El flag [Link] es muy útil. Al activarlo se ignoran


Los espacios (no escapados)
Las almohadillas y todo el texto posterior, hasta fin de lı́nea

ip = [Link](r"""
(\d{1,3}\.){3} # de 1 a 3 digitos y punto, repetido 3 veces
\d{1,3} # de 1 a 3 digitos
""", [Link])

URJC - EIF - 2024 Programación en Python (II) 48


Expresiones Regulares en python

Otros flags

[Link]
re.X
Permite comentarios dentro de la regex
[Link]
re.I
No distingue entre mayúsculas y minúsculas
[Link]
re.L
Hace que \w, \W, \b, \B, \s y \S tengan en cuenta las
locales
Para combinar más de un flag, se usa la barra vertical ('|'), que
es el operador or a nivel de bit.

URJC - EIF - 2024 Programación en Python (II) 49


Expresiones Regulares en python

Grupos
Un objeto SRE_Match devuelve en el atributo group las partes de
la cadena que han encajado en la regex
group[0] es el texto que ha encajado en la regex completa
#!/usr/bin/env python3
# [Link]
import re
ip = [Link](r"""
(\d{1,3}\.){3} # 1,2 o 3 digitos y punto, repetido 3 veces
\d{1,3} # 1,2 o 3 dı́gitos
""", [Link])
texto=r"""Mi correo es [Link]@[Link]
y mi dirección IP, [Link]"""

for linea in [Link]('\n'):


m=[Link](linea)
if m:
print([Link](0))

Ejecución:
[Link]

URJC - EIF - 2024 Programación en Python (II) 50


Expresiones Regulares en python

Los paréntesis
Como hemos visto, definen el ámbito y precedencia de los
demás operadores
Además, definen grupos. El resultado de cada búsqueda
devuelve en group[n] el grupo n-ésimo

URJC - EIF - 2024 Programación en Python (II) 51


Expresiones Regulares en python

#!/usr/bin/env python3
# [Link]
import re
correo_alumno = [Link](r"""
(
\b # Lı́mite de palabra
[\w.]+ # 1 o más caracteres de palabra o punto
\b # lı́mite de palabra
) # Hasta aquı́ el grupo 1
@
(alumnos\.urjc\.es) # Grupo 2
""", [Link])

texto=r"""Llegó un correo de [Link]@[Link] preguntando


si hay clase ma~nana"""

for linea in [Link]('\n'):


m=correo_alumno.search(linea)
if m:
print("Alumno: {}".format([Link](1))) # [Link]
print("Dominio: {}".format([Link](2))) # [Link]

URJC - EIF - 2024 Programación en Python (II) 52


Expresiones Regulares en python

Dentro de una regex, podemos hacer referencia a un grupo

#!/usr/bin/env python3
# [Link]
import re

regex=[Link](r"""(\b\w+\b) # Una palabra


\s+ # Espacios
\1 # Grupo 1: la misma palabra
""", [Link])

texto=r"""Buscando palabras repetidas repetidas"""

for linea in [Link]('\n'):


m=[Link](linea)
if m:
print([Link](1)) # Devuelve "repetidas"

URJC - EIF - 2024 Programación en Python (II) 53


Expresiones Regulares en python

Ejemplo de definición explı́cita de palabra española

#!/usr/bin/env python3
# [Link]
import re

regex=[Link](r"""
(\b # Lı́mite de palabra
n~
[\wáéı́óúÁÉÍÓÚ~NüÜ]+ # Palabra, incluyendo letras espa~
nolas
\b)
\s* # Espacios, opcionalmente
$ # Fin de lı́nea
""", [Link])

texto=r"""Buscando la última palabra de la lı́nea """

for linea in [Link]('\n'):


m=[Link](linea)
if m:
print([Link](1)) # Devuelve "lı́nea"

URJC - EIF - 2024 Programación en Python (II) 54


Expresiones Regulares en python

Sustituciones

Además de search y match, los objetos regex tienen el método


sub(reemplazo,cadena) que
Busca el patrón en la cadena
Si lo encuentra, reempleza el texto que ha encajado por
reemplazo
Dentro de reemplazo se pueden usar referencias a grupos
Devuelve el texto resultante

URJC - EIF - 2024 Programación en Python (II) 55


Expresiones Regulares en python

#!/usr/bin/env python3
# [Link]
import re
# reemplazamos los correos login@[Link] por
# [Correo de login en la URJC ]

correo_urjc = [Link](r"""
(
\b # Lı́mite de palabra
[\w.]+ # 1 o más caracteres de palabra o punto
\b # lı́mite de palabra
)
@urjc\.es
""", [Link])

texto="Si es necesario, escribe a [Link]@[Link]"


for linea in [Link]('\n'):
print(correo_urjc.sub(r"""[Correo de \1 en la URJC]""",linea))

Resultado de la ejecución
koji@mazinger:~/python$ ./[Link]
Si es necesario, escribe a [Correo de [Link] en la URJC]

URJC - EIF - 2024 Programación en Python (II) 56


Expresiones Regulares en python

Regex multilı́nea

Hasta ahora hemos procesado cada lı́nea de forma independiente


de las demás, lo cual es bastante frecuente
En este caso
El metacarácter '^' representa el principio de cadena, lo que
equivale al principio de lı́nea
El metacarácter '$' representa el fin de cadena, lo que
equivale al fin de lı́nea
El metacarácter '.' no encaja en el fin de lı́nea

URJC - EIF - 2024 Programación en Python (II) 57


Expresiones Regulares en python

Pero en otras ocasiones querremos aplicar la regex a más de una


lı́nea. Esto generalmente requiere de algunos flags adicionales
[Link]
re.S
Hace que el metacarácter '.' encaje en el fin de lı́nea
[Link]
re.M
Hace que el metacarácter '^' represente el principio de lı́nea
El metacarácter '$' representa el fin de lı́nea

URJC - EIF - 2024 Programación en Python (II) 58


Expresiones Regulares en python

#!/usr/bin/env python3
# [Link]
import re
regex=[Link](r"""
^ # Principio de lı́nea
(\b
n~
[\wáéı́óúÁÉÍÓÚ~N]+ # Palabra
\b) #
.* # Resto de la lı́nea
^ # Comienzo de lı́nea
\1 # La misma palabra
""", [Link]|[Link]|[Link])

texto=r"""En este ejemplo estamos


buscando dos lı́neas que comiencen igual
buscando lı́neas con primera palabra
coincidente
"""
m=[Link](texto)
if m:
print([Link](1)) # Devuelve "buscando"

URJC - EIF - 2024 Programación en Python (II) 59


Expresiones Regulares en python

Split con regex


Se puede trocear una cadena indicando con una regex cuál es el
separador
Ejemplo: queremos una lista con todos los unos consecutivos,
separados por ceros
>>> import re
>>> miregex=[Link](r'0+')
>>> [Link]('10011100011110001')
['1', '111', '1111', '1']

Atención: el separador, por definición, está entre dos elementos. No


antes del primero ni después del último.
En el siguiente ejemplo los ceros no se comportan como
separadores, por lo que el resultado no es exactamente el deseado
(aunque se acerca mucho)
>>> [Link]('00100111000111100010')
['', '1', '111', '1111', '1', '']

URJC - EIF - 2024 Programación en Python (II) 60

También podría gustarte