Expresiones regulares

octubre 11, 2015

Expresiones regulares

La librería de expresiones regulares de Python (RE), contiene operaciones de comparación de texto, puede encontrar fragmentos o patrones de tipo string o unicode. Generalmente se usa el símbolo " \ " (backslash) para indicar caracteres especiales. Un ejemplo de estos caracteres es "\n" que representa una nueva línea en un texto:

In [1]:
print "Este caracter \nparte la línea en 2"
Este caracter 
parte la línea en 2
In [2]:
# Importación de la librería de expresiones regulares en Python
import re

Para buscar determinado fragmento de texto dadas ciertas condiciones se usa el método search contenido en la librería re. Este método requiere de dos argumentos un patrón y el texto en el que se realiza la búsqueda. Al imprimir el resultado se ve que es un objeto tipo '_sre.SRE_Match'. Si no encuentra el patrón el resultado de la búsqueda es None

In [3]:
result = re.search('ins', 'Vasili Kadinsky')
print result
print type(result)
<_sre.SRE_Match object at 0x7f32ee686578>
<type '_sre.SRE_Match'>
In [4]:
result = re.search('arac', 'Caravaggio')
print result
None

Para ver el valor contenido en este objeto, en caso de encontrado el patrón, se usa el método group, que arroja el valor del patrón buscado.

In [5]:
result = re.search('ins', 'Vasili Kadinsky')
print result.group()
ins

Es posible hacer búsquedas con un patrón que dependa del texto alrededor de este, por ejemplo, se busca el patrón 'ins' nuevamente pero esta vez debe estar seguido de dos letras minúsculas. Para indicar cada letra siguiente se usa la expresión regular " \w ". Si se requiere una bśuqueda en al que las letras continuas sean mayúsculas se usa " \W ".

In [6]:
result = re.search('ins\w\w', 'Vasili Kadinsky')
print result.group()
insky

findall

Permite realizar búsquedas de un patrón en un string al igual que la función search, la diferencia es que search devuelve la primera coincidencia y findall encuentra todas las coincidencias

In [7]:
texto = u"Ella, ansiosa, Vuela y posa, En su palma sonrosada, Y allí mismo, ya saciada, Y de gozo temblorosa"
# El patrón describe un caracter con letras o números que terminen en rosa
# Uso del '+' en la siguiente sección *Repetición de patrones*
result = re.search('\w+rosa', texto)
print result.group()
sonrosa
In [8]:
result = re.findall('\w+rosa', texto)
print result
[u'sonrosa', u'temblorosa']

Expresiones regulares

Estas expresiones regulares hacen parte de un grupo de patrones básicos y su significado dentro de estos:

  • \w : abecedario en letras minúsculas, los números naturales y el guión bajo [a-z, 0-9, _]. Para las letras mayúsculas se usa \W.
  • . Cualquier carácter diferente a \n
  • \s Carácter de espacio: \n nueva línea, \t tabulación.
  • \d Números naturales.
  • ^ reconoce el comienzo de un string
  • $ reconoce el final de un string
  • ? reconoce el fragmento de string con o sin el carácter a su izquierda
  • {a} reconoce un fragmento con a repeticiones del carácter a su izquierda
  • [abc] Indica un conjunto de posibles coincidencias, en este caso puede concidir con 'a', 'b' o 'c'
In [9]:
texto = u'En la memoria tendré presente el horrible día'
In [10]:
# El punto reconoce cualquier carácter excepto \n (nueva línea)
result = re.findall('.en', texto)
print result
[u'ten', u'sen']
In [11]:
# Cada punto agrega un nuevo caracter al segmento de string encontrado
result = re.findall('..en', texto)

# Note que en el primer segmento el nuevo carácter es un espacio
print result
[u' ten', u'esen']
In [12]:
# \s reconoce todo tipo de carácteres de espacio
result = re.findall('\shorrible', texto)
print result
[u' horrible']
In [13]:
# No se reconoce el fragmento 'ente' porque, a pesar de que esta presente 
# en el texto, no está precedido por un espacio
result = re.findall('\sente', texto)
print result
[]
In [14]:
texto = 'Ima Sumac'
In [15]:
# ^ Reconoce el inicio de un string
result = re.findall('^I..', texto)
print result
['Ima']
In [16]:
# $ reconoce el final de un string
result = re.findall('..c$', texto)
print result
['mac']

Puede indicarse el fin del string sin decir exactamente algunos carácteres

In [17]:
result = re.findall('m..$', texto)
print result
['mac']
In [18]:
texto = 'despiert o despierto'
In [19]:
# Encuentra el segmento de string con o sin la *o* que tiene el símbolo
result = re.findall('despierto?', texto)
print result
['despiert', 'despierto']
In [20]:
texto = "ABBDDDEAEEABDCCBDDC"
# Se busca un fragmento en el que la D se repita 3 veces y sea precedida de la letra B
result = re.findall('BD{3}', texto)
print result
['BDDD']

También es posible dar un rango para el número de repeticiones

In [21]:
# Se busca un fragmento en el que la D se repita de 1 a 3 veces y sea precedida de la letra B
result = re.findall('BD{1,3}', texto)
print result
['BDDD', 'BD', 'BDD']
In [22]:
texto = 'Me gusta la pera pero como muchas manzanas'

# Encuentra fragmentos que comiencen en *per* y terminen en *a* o *o*
result = re.findall('per[ao]', texto)
print result
['pera', 'pero']

Repetición en los patrones

' + '

Reconoce 1 ó más repeticiones del caracter que se encuentre a la izquierda de este símbolo.

Si el patrón es 'm\w+', este busca la palabra que contenga una m y que seguida de esta hayan caracteres de tipo \w (a-z, 0-9, _). En este caso devuelve el string desde la m hasta un caracter que no sea de tipo \w

texto = "Hermann Melville"
# Se busca un string que comience por "He" y que le sigan caracteres de tipo \w
result = re.search('^He\w+', texto)
print result.group()
Hermann
# Se busca un string que termine en "lle" y que le antecedan caracteres de tipo \w
result = re.search('\w+lle$', texto)
print result.group()
Melville

' * '

Reconoce 0 ó más repeticiones del caracter que se encuentre a la izquierda

Si el patrón es 'AB', este reconoce 'A' y 'AB' con la cantidad de B* consecutivas que hayan en el string

texto = "ABBABDDDEAEECCC"
# Se busca un fragmento de string que sea A o que comience por A y sea seguido por B
result = re.findall('AB*', texto)
print result
['ABB', 'AB', 'A']

Combinaciones y generación de otros patrones

In [23]:
texto = 'La vida interior de Martin Frost'
In [24]:
result = re.findall('in*', texto)
print result
['i', 'in', 'i', 'in']

Pero al agregar ' ? ' al patrón el resultado será fragmentos de string que cumplan la condición pero con la menor longitud posible. En este caso el patrón ' in* ' encuentra ' i ' e ' i ' seguido de cuantos ' n ' haya en el string, por lo que al buscar con el patrón ' in*? ' el fragmento con menor longitud es ' i '. Se puede aplicar la misma lógica a comibaciones como ' +? ', '{a, b}? ' y ' ?? '.

In [25]:
result = re.findall('in*?', texto)
print result
['i', 'i', 'i', 'i']
In [26]:
texto = 'La vida interior de Martin Frost'

Encuentra un segmento de texto solo si es seguido por lo indicado en el paréntesis en este caso ' Frost'

In [27]:
result = re.findall('.+Martin(?= Frost)', texto)
print result
['La vida interior de Martin']

Lo contrario a lo anteriror es con el símbolo ' ! '. Encuentra en texto solo si no es seguido por lo indicado en el paréntesis

In [28]:
result = re.findall('.+Martin(?!Rogelio)', texto)
print result
['La vida interior de Martin']

También es posible encontrar fragmentos de un string indicando lo que le precede con esta sintaxis. En el paréntesis se indica que caracteres debe ir antes.

In [29]:
# Encuentra un string solo si es precedido por 'La '
result = re.findall('(?<=La )vida interior.+', texto)
print result
['vida interior de Martin Frost']

La negación es igualmente con el signo ' ! '

In [30]:
# Encuentra un string solo si no es precedido por 'La '
result = re.findall('(?<!La )vida interior.+', texto)
print result
[]

Búsqueda de caracteres usados como patrón

Caracteres que no pueden ser usados como patrón, puesto que son reservados para describirlos:

  • . ^ $ * + ? { [ ] \ | ( )

Para utilizar estos símbolos como parte de un patrón de búsqueda deben ser precedidos por el backslash " \ "

In [31]:
texto = "Qué es esto?"
print texto
Qué es esto?

Al buscar el caractér si el backslash la salida no corresponde al patrón buscado, puesto que este realiza la operación dada por ser una expresión regular.

In [32]:
result = re.search('o\?', texto)
print result.group()
o?

sub

Este método permite sustituir fragmentos de un string mediante un patrón y una función. Por ejemplo en la frase "We die in proportion to the words we fling around us" Se reemplazarán las palabras que comiencen por la letra ' w ' o ' W ' por la misma palabra en mayúscula.

Se importa la librería locale y se especifica la región para que se reconoczca dentro de los patrones los caracteres especiales del español, como la ñ y las letras tildadas, como letras.

In [33]:
frase = "We die in proportion to the words we fling around us"

# se revisa primero con el método re.findall que el patrón seleccionado sea el correcto
re.findall('[wW]\w+', frase)
Out[33]:
['We', 'words', 'we']
In [34]:
re.sub('[wW]\w+', lambda x: x.group().upper(), frase)
Out[34]:
'WE die in proportion to the WORDS WE fling around us'

You Might Also Like

0 comments

Apoyado por: