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