Las expresiones regulares en Python
Las expresiones regulares son una serie de patrones que especifican la regla o norma que se ha de seguir para localizar coincidencias dentro de una cadena de texto .
.search: Busca la primera coincidencia de texto1 dentro de texto2
Resultado = re.search(Texto1, Texto2)
Texto1: Texto que se busca en Texto2
Texto2: Texto donde se busca Texto1
Si Texto1 está dentro de Texto2, search devuelve un objeto tipo Match
Resultado = <re.Match object; span=(pos1, pos2), match= Texto_1>
Pos1 = posición de inicio de Texto1
Pos2 = Posición de fin de Texto1
Un objeto tipo Match es un objeto de coincidencia por lo que siempre tiene un valor booleano de True.
Resultado= re.search(patron, cadena_texto)
if Resultado:
process(Resultado)
Se puede extraer información del objeto match con los siguientes métodos:
group( ): Retorna la cadena de caracteres que coincide con la expresión regular
start( ): Retorna la posición de inicio de la coincidencia
end( ): Retorna la posición final de la coincidencia
span( ): Retorna una tupla que contiene la posición inicial y final de coincidencia
Si no hay coincidencia devolverá None
.findall: Busca
todas las coincidencias de texto1
dentro de texto2
Resultado = re.findall(Texto1, Texto2)
Texto1: Texto que se busca en Texto2
Texto2: Texto donde se busca Texto1
Si Texto1 está dentro de Texto2, search devuelve una lista con todas las coincidencias
Resultado = [Texto1(1), Texto1(2), Texto1(3)… Texto(n)] para n coincidencias.
Len(Resultado) = n
Si no hay coincidencia devolverá None
Acento circunflejo (^) : Comprueba si un texto comienza por el string indicado.
Resultado = re.seach(‘^Hola’, Texto2)
‘^Hola’
= Se busca la cadena ‘Hola’ al principio de
Texto2
Texto2 = Texto donde se
busca al inicio ‘Hola’
Esta acción es lo mismo
que utilizar la función re.match(‘Hola’,
Texto2)
Signo dollar ($) : Comprueba si un texto finaliza por el string indicado.
Resultado = re.seach(‘Hola$’, Texto2)
‘Hola$’
= Se busca la cadena ‘Hola’ al final de
Texto2
Texto2 = Texto donde se
busca al final ‘Hola’
La utilización de corchetes [ ] en las expresiones
regulares.
Esta opción permite
localizar un conjunto de caracteres dentro de un texto con lógica tipo OR, es
decir, coincidencias con alguno de ellos.
Resultado = re.search(‘[ad]’, Texto2)
Search devolverá un objeto
match si el carácter ‘a’ o el carácter ‘m’ se encuentran dentro de Texto2, sino devolverá None.
Se puede hacer una
búsqueda utilizando el rango de valores entre dos caracteres.
Resultado = re.search(‘[a-d]’, Texto2)
Search devolverá un objeto
match si el carácter ‘a’, ‘b’, ‘c’ o ‘d’ se encuentran dentro de Texto2, sino devolverá None.
Este método es muy útil si
queremos buscar alguna palabra con diversas posibilidades.
Resultado = re.search(‘car[áa]cteres’, Texto2)
Buscará dentro de
Texto2 una coincidencia con ‘caracteres’ o ‘carácteres’
Ejemplos:
Resultado: re.search(‘^[an]’, Texto2)
La variable resultado
contendrá un match si Texto2 comienza con ‘a’
o con ‘n’. Si no es así devolverá None.
Resultado: re.search(‘[an]$’, Texto2)
La variable resultado
contendrá un match si Texto2 finaliza con ‘a’
o con ‘n’. Si no es así devolverá None.
El metacarácter ^ dentro
de los corchetes y al principio indica la “no coincidencia” con los caracteres
que le siguen.
Resultado: re.findall(‘^[^an]’, Texto2)
La variable resultado
contendrá un match si Texto2 comienza con cualquier carácter que no sea
‘a’ o ‘n’.
Si no es así devolverá None.
Los conjuntos predefinidos de caracteres
Las representaciones de conjuntos predefinidos de caracteres vienen precedidos de la barra inversa \, y tenemos los siguientes:
\d: Coincide con cualquier dígito decimal
\D: Coincide con cualquier carácter que no sea un dígito
\s: Coincide con cualquier carácter de espacio en blanco
\S: Coincide con cualquier carácter que no sea un espacio en blanco
\w: Coincide con cualquier carácter alfanumérico
\W: Coincide con cualquier carácter no alfanumérico
En python se utiliza
igualmente la barra inversa (\) para los literales de cadena o secuencias de
escape, lo que podría crear un conflicto a la hora de crear un patrón de
búsqueda en una expresión regular. Cualquier uso de uno de los valores predefinidos
anteriores en una expresión regular generará en python un SyntaxWarning, ya que
python no lo detecta como una secuencia de escape válida.
Para evitar este aviso,
que podría generar posteriormente un Syntaxerror, se utiliza la notación de cadena
row de python ‘r’ para los patrones de expresiones regulares. De esta manera
cualquier valor predefinido anterior no será considerado por python como una
secuencia de escape, sino como un valor literal de dos caracteres; la barra
invertida (\) y el valor predefinido.
Ejemplo: re.search(r ‘\d\d’, texto2) à busca la primera secuencia de dos números seguidos en Texto2
La utilización de operadores de repetición.
Las llaves { }:
Esta opción indica un
rango de repeticiones que debe haber en el carácter que le precede.
Resultado = re.findall(r‘\d{3}’,
Texto2)
Devuelve una lista cuyos
elementos son la coincidencia de tres números seguidos en Texto2.
Ejemplo: Texto2 = “1234p45r456345-123-08”
Resultado = [‘123’, ‘456’,
‘345’, ‘123’]
Podemos indicar dos
índices dentro de las llaves. El primero indica el mínimo de repeticiones y el
segundo el máximo de repeticiones.
Resultado = re.findall(r‘\d{2,4}’,
Texto2) nota:
Sin espacios entre los índices y la coma
Devuelve una lista con
todas las agrupaciones posibles de 4, 3 y 2 caracteres en Texto2. Primero
intentará hacer agrupaciones del índice mayor, y si no es posible luego
intentará hacerlas con el índice inmediato inferior, y así sucesivamente hasta
llegar al índice menor.
Ejemplo: Texto2 = “1234p45r456345-123-08”
Resultado = ['1234', '45',
'4563', '45', '123', '08']
Al realizar la agrupación
‘4563’ los siguientes números disponibles
son ‘45’. Como no puede agrupar 4 números,
lo intenta con 3. Como no puede agrupar tampoco 3 números lo intenta con 2. En
este caso se produce la agrupación ‘45’.
Cuando utilizamos
caracteres concretos podemos indicar la agrupación de estos con las llaves
Texto2 =
"1234p45r456234135-123-08"
Resultado =
re.findall('[123]{2}', Texto2)
Busca todos los resultados
posibles de los conjuntos de caracteres indicados entre corchetes agrupados de
dos en dos dentro de Texto2 en una lista.
Resultado = ['12', '23',
'13', '12']
Localizados en "1234p45r456234135-123-08"
El signo *:
Este metacarácter indica
que el carácter que le precede puede repetirse 0 o más veces seguidas.
Texto2 =
"123334p45r456-124123234135-123-08"
Resultado =
re.findall('23*4', Texto2)
Devuelve una lista con las
agrupaciones de números que empiezan por 2 y acaban por 4, teniendo en medio 0
o más números 3.
Resultado =['23334', '24',
'234']
Lo coge de = "123334p45r456-124123234135-123-08"
Este metacarácter indica
que el carácter que le precede puede repetirse 1 o más veces seguidas.
Resultado = re.findall(r'\d+',
Texto2)
Devuelve una lista con las
mayores agrupaciones de números que se puedan realizar
Ejemplo: Texto2 =
"1234p45r456345-123-08"
Resultado = ['1234', '45',
'456345', '123', '08']
El metacarácter + es lo
mismo que {1,}
Ejemplo2:
Texto2= "1234p45r456345-123-08"
Resultado = re.search(r'-\d+', Texto2).group()
Busca en Texto2 la primera
coincidencia que tenga un guión(-) seguido del mayor conjunto de números
posibles, y devuelve la cadena de caracteres de la expresión regular del match que
retorna re.search().
Resultado = ‘-123’
Los paréntesis ( ):
El uso de paréntesis dentro de un patrón de búsqueda localiza el conjunto unido de caracteres entre paréntesis a la vez que realiza un recorte de lo que devolverá el método utilizado.
Ejemplo1:
Texto2 =
"1234p45r456345-123-08"
Resultado = re.findall(r'-\d{3}',
Texto2)
Resultado = [‘-123’]
Si colocamos el paréntesis
nos devolverá solo lo que se encuentre en él siempre que haya coincidencia con
el total del patrón.
Resultado = re.findall(r'-(\d{3})',
Texto2) nota: busca ‘-\d{3}’ pero devuelve
‘\d{3}’
Resultado = [‘123’]
Ejemplo2:
Texto2 =
"123334p45r456-123123234135-123-08"
Resultado =
re.findall('(123)+', Texto2)
Busca en Texto2 todas las
coincidencias de la cadena ‘123’ o de agrupaciones de repeticiones de la misma
cadena, por ejemplo ‘123123’ o ‘123123123’, etc… y devuelve el recorte (123) en
una lista.
Resultado = ['123',
'123',
'123']
Localizados en "123334p45r456-123123234135-123-08"
La cadena ‘123123’ es única, debido al metacarácter +, pero se recorta la salida a (123)
El uso del punto sustituye
cualquier carácter en esa posición.
Texto2 =
"1234p45r456234135-123-08"
Resultado =
re.findall('.4', Texto2)
Busca cualquier conjunto
de coincidencias entre un carácter cualquiera y el número 4 dentro de Texto2.
Resultado = ['34', 'p4',
'r4', '34']
Lo encuentra en "1234p45r456234135-123-08"
Ejemplo2:
Texto2 = "1234p45r456234135-123-08"
Resultado =
re.findall('.{3}4', Texto2)
Busca cualquier conjunto
de coincidencias entre tres caracteres cualesquiera seguidos del número 4
dentro de Texto2 y los devuelve en una lista.
Resultado = ['1234',
'45r4', '6234']
Los localiza en "1234p45r456234135-123-08"
El signo ? :
El uso del signo ? indica
que el carácter que le precede puede estar presente o no en el patrón de
búsqueda.
Ejemplo:
Texto2 =
"1234p45r456-124123234135-123-08"
Resultado =
re.findall('23?4', Texto2)
Buscará todas las
agrupaciones de números que empiecen por 2 y terminen por cuatro, entre el 2 y
el 4 podrá haber un 3 o no.
Resultado: ['234', '24',
'234']
Localizados en "1234p45r456-124123234135-123-08"
1)
Supongamos una lista con datos de empresas:
Lista_empresas =
["Automotor SL - 971345678 - B07123456",
"Garaje Palma S.A - 695236456 -
A-07456789",
"Taller Planas SA - 789456123 - B
45123456",
"Chapistería Olmo SA - 654321987 -
B-45678945"]
El nif de las empresas
está escrito de varias formas. Sin nada después de la letra, con guión o con un
espacio. Extraer una lista con los NIf
de las empresas.
import re
Lista_empresas = ["Automotor
SL - 971345678 - B07123456",
"Garaje
Palma S.A - 695236456 - A-07456789",
"Taller
Planas SA - 789456123 - B 45123456",
"Chapistería Olmo SA - 654321987 -
B-45678945"]
for empresa in
Lista_empresas:
resultado = re.findall(r'\s([^\d-].?\d{8})',empresa)
print
(resultado)
Resultado:
['B07123456']
['A-07456789']
['B 45123456']
['B-45678945']
Estudiemos el patrón (r'\s([^\d-].?\d{8})
Busca agrupaciones de
caracteres que…
r à Trata los valores predefinidos \s y \d como
caracteres literales en python
para evitar el SystaxWarning
\s à Empiezan por un espacio
[^\d-] à
El siguiente carácter nos un número ni un guión
.? à
Seguidamente puede haber cualquier carácter, espacio, etc o no haber nada
\d{8} à Por último tenemos 8 números seguidos.
([^\d-].?\d{8})
à El paréntesis excluyendo el espacio nos devuelve
únicamente el Nif
2)
Escribir una función que valide contraseñas con las
siguientes normas.
1-.
Mínimo 10 caracteres
2-.
Mínimo una letra mayúscula y una minúscula
3-.
Mínimo dos dígitos
4-.
Mínimo dos caracteres especiales de los siguientes @$^/!?*&.
import re
def validarContrasenya(contrasenya):
valida = True
if len(contrasenya)< 10:
print("La contraseña debe tener al menos 10 caracteres")
valida = False
minus = len(re.findall("[a-z]",contrasenya))
if
minus< 1:
print("La contraseña debe incluir al menos una letra minúscula")
valida = False
mayus =
len(re.findall("[A-Z]",contrasenya))
if
mayus< 1:
print("La contraseña debe incluir al menos una letra mayúscula")
valida = False
numeros =
len(re.findall("[0-9]",contrasenya))
if
numeros< 2:
print("La contraseña debe incluir al menos dos números")
valida = False
caract = len(re.findall("[@$^/!?*&]",contrasenya))
if
caract< 2:
print("La contraseña debe incluir al menos dos caracteres
especiales")
valida = False
if
valida:
print("Contraseña válida")
Llamadas a la función y resultados:
print("Evaluación contraseña 'jnjty3aej58*':")
validarContrasenya("jnjty3aej58*':")
print("\nEvaluación contraseña 'KLkvj@bvk23*a':")
validarContrasenya("KLkvj@bvk23*a")
print("\nEvaluación contraseña '$4kjG45':")
validarContrasenya("$4kjG45")
Resultados:
Evaluación contraseña 'jnjty3aej58*':
La contraseña debe incluir al menos una letra mayúscula
La contraseña debe incluir al menos dos caracteres especiales
Evaluación contraseña 'KLkvj@bvk23*a':
Contraseña válida
Evaluación contraseña '$4kjG45':
La contraseña debe tener al menos 10 caracteres
La contraseña debe incluir al menos dos caracteres especiales
Utilizar un patrón de expresión regular como un
objeto: re.compile
La función re.compile compila un patrón de expresión regular en un objeto de expresión regular.
Se creará una variable tipo re, a través de la función compile, que contendrá el patrón de la expresión regular. A partir de ahí, esa variable se podrá utilizar con el conjunto de métodos incorporados en la librería re para aplicar el patrón a las cadenas de texto indicadas.
Ejemplo:
Variable_patron = re.compile(patron)
Resultado= variable_patron.match(Texto1)
Esto es equivalente a…
Resultado = re.match(Texto1)
La ventaja de crear el patrón como un objeto estriba en la reutilización de código para patrones muy habituales (comprobar la validez de contraseñas, datos comunes como Nifes, teléfonos, etc) ya que .compile es más rápido a la hora de buscar patrones.
formato_nif = re.compile('\s([^\d-].?\d{8})')
for empresa in Lista_empresas:
resultado = formato_nif.findall(empresa)
print (resultado)
No hay comentarios:
Publicar un comentario