Expresiones regulares

Iniciado por Dharok, Febrero 23, 2010, 11:41:57 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

En este capitulo explicare el uso de las expresiones regulares en Ruby. Es una de las cosas que menos me gustan, ya que puede resultar algo lioso, pero que nos puede ser muy util codeando y nos puede ahorrar muchas linias de programa.

Se utilizan para comprobar si un texto (string ) contiene el patron que nosotros establezcamos. Es decir, comprobar si determinada variable string contiene el patron que nosotros queramos.

Las expresiones regulares se encierran entre //, y el operador para comprobar 'si contiene' es =~

Veamoslo con ejemplos:
Código: text
irb
irb(main):001:0> cadena = "capitulo de expresiones regulares"
=> "capitulo de expresiones regulares"
irb(main):002:0> if cadena =~ /capitulo/
irb(main):003:1> ^C
irb(main):003:0>
irb(main):004:0* exit
protos@diego-desktop:~$ irb
irb(main):001:0> cadena = "Esto es el capitulo de expresiones regulares"
=> "Esto es el capitulo de expresiones regulares"
irb(main):002:0> if cadena =~ /guia/
irb(main):003:1> puts 'Es una guia'
irb(main):004:1> elsif cadena =~ /capitulo/
irb(main):005:1> puts 'es un capitulo'
irb(main):006:1> end
es un capitulo

Como vemos creamos una cadena, y comprobamos si contiene en primera instancia, guia y en segunda capitulo, como no contiene el patro 'guia' pero si el patron 'capitulo', pues se efectuara lo del elsif...
Hasta aqui sencillo ;)

Algunas veces nos interesara buscar patrones que no son exactos, por ejemplo, no me interesa saber si la string contiene especificamente 'capitulo', sino cualquier palabra que empiece por c y acabe en o ya me sirve...

Antes de resolver ese problema, os dejo la siguiente tabla, son unas abreviaciones que nos ofrecen las expresiones regulares:
expresion          significado
.    cualquier caracter
[]    especificacion por rango. P.ej: [a-z], una letra de la a, a la z
\w    letra o numero; es lo mismo que [0-9A-Za-z]
\W    cualquier caracter que no sea letra o numero
\s    caracter de espacio; es lo mismo que [ \t\n\r\f]
\S    cualquier caracter que no sea de espacio
\d    numero; lo mismo que [0-9]
\D    cualquier caracter que no sea un numero
\b    retroceso (0x08), si esta dentro de un rango
\b    limite de palabra, si NO esta dentro de un rango
\B    no limite de palabra
*    cero o mas repeticiones de lo que le precede
+    una o mas repeticiones de lo que le precede
$    fin de la linea
{m,n}    como menos m, y como mucho n repeticioes de lo que le precede
?    al menos una repeticion de lo que le precede; lo mismo que {0,1}
()    agrupar expresiones
||    operador logico O, busca lo de antes o lo despues


(encontrareis mas expresiones asi en la documentacion :P)

Estos son las expresiones especiales, que nos sirven para abreviar, sintetizar, o encontrar rangos, repeticiones etc... En el caso de que queramos buscar por ejemplo el signo + en una string, resulta que si ponemos + entre // lo detectar? como expresion especial y buscar? una o mas repeticiones de lo que le precede...Para solucionar est, cuando queramos encontrar cualquier expresion de las de la tabla, no su significado, lo escaparemos con \
Ejemplo:
Código: text
/s+a/ buscar? ssa o sssa, sssssa, ssssssa, etc
/s\+a/ buscar? s+a.

Es importante saberse las abreviaciones, ya que nos seran muy utiles para las expresiones regulares, si alguien no entiende alguna expresion de las anteriores, que pregunte porfavor :)

Y es aqui donde se complica la cosa, ya que con tantas expresiones, a veces las expresiones regulares se hacen inentendibles, o se ven muchos simbolos y lian a uno....xD, esto es muy importante saberse los simbolos y practicar.

Vamos a ver otro ejemplo sencillito:
Código: text
cadena = "perro perra paco poco poca pato mato peto pete mete sota"
if cadena =~ /p\w*o\s/
puts "El string contiene algo que empieza por p y acaba por o"
end

Analizemos el patron: /p\w*o\s/
Primero una p, luego cualquier caracter (\w) repetido las veces que sea (*), luego una o, y luego un espacio (\s)
Con eso concordaria perro, porro, paarrrooruweqno , etc....


VARIABLES $

Este tipo de variables solo surgen cuando agrupamos alguna expresion con (), pongamos un ejemplo y lo veremos:
Sigamos con el mismo ejemplo tonto de antes
Código: text
cadena = "perro"
if cadena =~ /p(\w+)o/
puts $1
end

Y esto nos dara ''err''
Explicacion: Hemos buscado algo que empiece por p, contenga varias vececes cualquier caracter y acabe por o, pero hemos puesto entre parentesis lo que haya entre la p y la o. Las variables $ apuntan a las agrupaciones de expresiones (a lo que hayamos puesto entre () ), por eso nosotros ponemos $1 y nos devuelve lo que en nuestra cadena correspondia a (\w+). Si tuvieramos dos expresiones agrupadas entre parentesis, $1 apuntaria a la primera agrupacion, $2 a la segunda, etc....

Hmm esto igual es algo lioso, si no se entiende preguntad que es que me explico mal xD.
MATCH
Bueno, hemos visto que para comprobar si una string contiene un patron, lo haciamos con //, realmente se puede hacer de otra manera tambien:
Código: text
var=patron.match(string)

Ejemplo:
Código: text
var=/a/.match("esto contiene la a?")

Si no hay coincidencias se te devolvera un nil
Si hay coincidencia tendremos un objeto MatchData apuntado por la variable var.
Este objeto almacenara mucha info, de entrada un true booleano porque ha hayado coincidencias, y luego almacenara tambien
en que caracter del string empieza la coincidencia, cuanto ocupa la coincidencia del string, ademas de las $ entre otras cosas, para ver los metodos de la clase MatchData que nos permiten hacer esas cosas acudimos a la pagina de la documentacion oficial porque esta muy bien hecho y a mi no me apetece repasar todos los metodos:
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta


Y con esto voy acabando el capitulo, pondre ejercicios de expresiones regulares si alguien quiere y no le resulta insoportable, casi casi son como jeroglificos, con lo de ejercicio me refiero a algo asi:

Daria coincidencias
string = " me gusta el basket"
patron = /\s(\S\D)\s(g\w*a)\s(el).*/

De entrada podeis contestar aqui mismo este...si quereis mas los preparo ;)
Bibliografia:
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta