Libertonia
Portada · Todo · Software Libre · Desarrolladores · Comunidad · Internet · Tecnología · Meta · Diarios
Expresiones regulares en python

Programación
Por Ariel
departamento dándole-a-la-tecla , Sección Desarrolladores
Puesto a las Mon Jan 9th, 2006 at 04:08:17 PM CET
Desde el pan con nocilla, no se ha inventado mejor que las expresiones regulares. Una expresión regular es, básicamente, un patrón que describe a un cierto texto. Si has estudiado informática (no ordenadores, ni procesadores de texto) sabrás algo de las matemáticas (sí, la informática tiene algo que ver con las matemáticas) que hay detrás de todo esto. Sin embargo, aquí no voy hablar de eso, sino de cómo utilizar expresiones regulares en Python a través del módulo re.

[Nota del editor, por iarenaza] Editado y enviado por un admin aburrido para que Ariel no tenga que darse la paliza con la edición y los colorines (que por defecto no iban a salir). No os acostumbréis, este admin no se suele aburrir con frecuencia...

 


Lo básico

Para empezar veamos un ejemplo sencillo. Puedes probar todo esto utilizando el intérprete interactivo de comandos:

 

>>> import re
>>> if (re.search("b", "abc")):
...    print "b está en abc"

b está en abc

El ejemplo es claro, se busca el patrón b en la cadena abc, utilizando la función search del módulo re. Veamos algo parecido utilizando una expresión un poco más complicada:

 
>>> if (re.search("\Aa[0-9].*(end|fin)$", "a7fin")):
...    print "se ha encontrado el patrón"

...
se ha encontrado el patrón
>>> if (re.search("\Aa[0-9].*(end|fin)$", "a2 lo que quiera fin")):
...    print "se ha encontrado el patrón"

...
se ha encontrado el patrón

En este caso, todas las cadenas que comienzen (\A) con a seguidas de un número ([0-9]), y de cualquier secuencia de caracteres (.*) y terminadas ($) en end o fin ((end|fin)) encajarán con el patrón \Aa[0-9].*(end|fin)$. Sencillo ¿no?

En el ejemplo anterior hemos visto que pasamos como parámetro la expresión regular y la cadena en la que queremos buscar. Esto está bien si queremos aplicar la expresión regular una sola vez. Sin embargo, si vamos a utilizar la expresión regular varias veces, que es lo habitual, por motivos de eficiencia conviene compilar la expresión creando un objeto expresión regular. Veamos más ejemplos:

 
>>> pattern = re.compile ('H.*-HRV_.*-0000(19|2[01234])_.*$')
>>> name_files = [ 
     'H-000-MSG1__-MSG1________-HRV______-000019___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000020___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000021___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000022___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000023___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000024___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000025___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000001___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000005___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000010___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000015___-200601040930-C_',
...  'H-000-MSG1__-MSG1________-HRV______-000018___-200601040930-C_' 
     ]

>>> for name in name_files:
...    if (pattern.search(name)):
...        print name + " OK"

...    else:
...        print name + " NO OK"
...
H-000-MSG1__-MSG1________-HRV______-000019___-200601040930-C_ OK
H-000-MSG1__-MSG1________-HRV______-000020___-200601040930-C_ OK
H-000-MSG1__-MSG1________-HRV______-000021___-200601040930-C_ OK
H-000-MSG1__-MSG1________-HRV______-000022___-200601040930-C_ OK
H-000-MSG1__-MSG1________-HRV______-000023___-200601040930-C_ OK
H-000-MSG1__-MSG1________-HRV______-000024___-200601040930-C_ OK
H-000-MSG1__-MSG1________-HRV______-000025___-200601040930-C_ NO OK
H-000-MSG1__-MSG1________-HRV______-000001___-200601040930-C_ NO OK
H-000-MSG1__-MSG1________-HRV______-000005___-200601040930-C_ NO OK
H-000-MSG1__-MSG1________-HRV______-000010___-200601040930-C_ NO OK
H-000-MSG1__-MSG1________-HRV______-000015___-200601040930-C_ NO OK
H-000-MSG1__-MSG1________-HRV______-000018___-200601040930-C_ NO OK

Este ejemplo está extraido de Meteogest, que hace uso de expresiones regulares para decidir qué operaciones realizar con archivos basándose en su nombre. En este caso sólo interesan los ficheros que en el penúltimo campo, su valor sea del 19 al 24. El patrón utilizado es sencillo, y obviamente, para este ejemplo podría simplificarse, pero he querido conservarlo tal y como está en el fichero de configuración de ejemplo de Meteogest.

Nótese que las expresiones regulares distinguen entre mayúsculas y minúsculas por lo que:

 
>>> pattern = re.compile ('H')

>>> result = pattern.search('aloha')
>>> result == None
True

En cambio, si:

 

>>> pattern = re.compile ('H', re.IGNORECASE)
>>> result = pattern.search('aloha')

>>> result == None
False

Puedes consultar otros flags a la hora de construir un patrón en la documentación del módulo re.

También podemos aplicar split con expresiones regulares, lo que es realmente útil:

 
>>> pattern = re.compile ('a[bc]')

>>> text = 'e8acjhf90abcklhd78ac867acaba8'
>>> pattern.split(text)
['e8', 'jhf90', 'cklhd78', '867', '', 'a8']
search Vs match

Si se observan los métodos de los objetos expresión regular, se verá que hay dos funciones, search y match. La direferencia entre ambas es que search busca en toda la cadena mientras que match sólo lo hace al principio.

Utilizaremos un patrón útil para decidir si en una cadena aparece el carácter ".". Como es un caracter que tiene un significado en expresiones regulares, es necesario utilizar el caracter de escape \:

 
>>> pattern = re.compile ('\.')

>>> result = pattern.search ('.gnome')
>>> result == None
False
>>> result = pattern.search ('gno.me')

>>> result == None
False
>>> result = pattern.match ('.gnome')
>>> result == None

False
>>> result = pattern.match ('gno.me')
>>> result == None
True

Por tanto se puede decir que search("\Apattern", text) es lo mismo match(pattern, text).

Los objetos Match

Hasta ahora hemos evaluado expresiones y decidido si verifican un patrón en función de si el valor de retorno es None o no. En Python None se evalúa como False por lo que es adecuado para estructuras condicionales. Sin embargo, cuando el valor de retorno no es None, se devuelve un objeto de tipo Match (que se evalúa como cualquier objeto como True). Veamos qué métodos contiene:

 
>>> pattern = re.compile ('a[bc]')
>>> result = pattern.search ('e8acjhf90abcklhd78ac867acaba8')

>>> dir (result)
['__copy__', '__deepcopy__', 'end', 'expand', 
'group', 'groupdict', 'groups', 'span', 'start']

>>> result.string
'e8acjhf90abcklhd78ac867acaba8'
>>> result.string[result.start():result.end()]

'ac'

Observando la cadena del ejemplo, vemos que el patrón se repite más de una vez. Para procesar cada uno de ellos:

 
>>> text = 'e8acjhf90abcklhd78ac867acaba8'
>>> iterator = pattern.finditer (text)

>>> for result in iterator:
...  print text[result.start():result.end()]

ac
ab
ac
ac
ab

Finalmente, el método group. Podemos dar un nombre a uno o un conjunto de elementos del patrón y luego referirnos a ellos. Como siempre, un ejemplo es mucho más útil que cualquier explicación:

 
>>> pattern = re.compile ('(?P<name>.+)\.(?P<extension>.+)')

>>> result = pattern.match ('hello.txt')
>>> result.group('name')
'hello'

>>> result.group('extension')
'txt'
Conclusión

Y eso es todo. Conviene conocer muy bien las herramientas con las que contamos a la hora de programar soluciones a nuestros problemas. La expresiones regulares son una herramienta muy útil, cuya potencia sólo se descubre cuando se necesita hacer uso extensivo de ellas. Casi cualquier operación de manipulación de cadenas se puede hacer de manera eficiente con expresiones regulares. Buscar patrones en textos es muy sencillo, así como validar que determinadas cadenas cumplan ciertas condiciones. Por ejemplo, pueden buscar en Internet expresiones regulares que verifiquen si una dirección de correo electrónico es o no correcta (puede ser más complicado de lo que parece si se es estricto) e integrar esta verificación en sus aplicaciones. E infinitas cosas más.

< Acerca de Wikipedia (14 comments) | Ponga una zaurus en su vida (210 comments) >
Enlaces Relacionados
· Python
· re
· More on Programación
· Also by Ariel

Menu
· crear cuenta
· FAQ
· búsqueda
· Fuentes de Noticias

Login
Nueva cuenta
Usuario:
Contraseña:

Ver: Modo: Orden:
Expresiones regulares en python | 3 comentarios (2 temáticos, 1 editoriales, 0 ocultos)
Regular Expression HOWTO (none / 0) (#2)
por toci (forodejazz (arroba) gmail (punto) com) a las Mon Jan 9th, 2006 at 02:45:33 PM CET
(Información Usuario) http://davidasorey.net

En inglés tenemos el estupendo "Regular Expression HOWTO".

En el libro "Dive into python" también hay algunos ejemplos. Saludos.



 
Enlace al artículo original (none / 0) (#3)
por Ariel a las Mon Jan 9th, 2006 at 05:59:55 PM CET
(Información Usuario) http://www.milugar.net

Pues eso:

Usando expresiones regulares en Python

--
Un saludo,
Visita mi lugar


 
Expresiones regulares en python | 3 comentarios (2 temáticos, 1 editoriales, 0 ocultos)
Ver: Modo: Orden:

ecol Logo Powered by Scoop
Todas las Marcas Registradas y copyrights de esta página son propiedad de sus respectivos dueños.
Los comentarios son propiedad del que los escribe.
Los iconos de las noticias y el logotipo son propiedad de Javier Malonda.
El Resto © 2002 Escomposlinux.org y aledaños.

Puedes sindicar los contenidos de libertonia en formato RSS 1.0 y RDF 0.9. También se puede sindicar la cola de envíos pendientes de moderación.

El proyecto escomposlinux.org está dedicado a la memoria de tas

crear cuenta | faq | búsqueda