Expresiones regulares en Ruby – No te dejes intimidar – Primera parte


Ruby!!!Las expresiones regulares normalmente, se ven desde un punto de vista intimidatorio, bueno así las vi yo mismo y alguna vez a día de hoy también , pero como a todo hay que ponerse a ello y entenderlas, para que dejemos de lado su cara intimidatoria, sea cual sea. Pero realmente tenemos que preguntarnos ¿Qué nos dejan hacer las expresiones regulares? 

En el libro de Programming Ruby 1.9 de Dave Thomas, hay un capítulo dedicado a las expresiones regulares (recomiendo leer el libro) que dice algo asó como:

Una expresión regular viene a ser un patrón, que se ajusta a un string para que coincida o no, dependiendo de lo que queremos obtener e intentar hacer con las expresiones regulares, un test, extraer o cambiar, es decir, que podemos probar una cadena para ver si coincide con el patrón determinado que componemos o podemos extraer una cadena o alguna parte que nos puede interesar que coincide con nuestro patrón o finalmente podemos cambiar una cadena, en sustitución de las reglas que responden nuestro patrón con otro texto. Dicho esto, ¿no te parece una potente herramienta, si la sabemos interpretar o entender?

Arrancamos y comenzamos viendo que lo habitual es, ver que cualquier expresión regular debe comenzar y terminar con / y con la apariencia de /…./ y también hay que considerar los caracteres como:

 . el punto coincide con cualquier carácter excepto una línea nueva 

| el pipeline es un condicional de una u otra

 ( ) para agrupar los paréntesis

 [ ] que coincida cualquier carácter que esté dentro de los corchetes

 { } coincidencia exacta con las llaves

 + coincidencias en 1 o más ocurrencias de la expresión anterior

 \ para poder componer nuestro patrón con elementos especiales como los paréntesis

 ^ coincidencia al comienzo de la línea

 $ coincidencia al final de la línea

 * coincide 0 o más veces

 ? coincide una o más veces

y todos ellos son para componer nuestro patrón. Te presento al operador =~ que comprueba nuestro string y nuestro patrón.

Veamos algunos ejemplos de inicio y los resultados obtenidos:

> «Hello regular expressions» =~ /expressions/
=> 14 la posión en la que se encuantra nuestra expresión a buscar, nos dice que la ha encontrado en la posición 14
> «Hello regular expressions» =~ /expression/
=> 14
> «Hello regular expressions» =~ /Expression/
=> nil en este caso no la ha encontrado
> «Hello regular expressions» =~ /Express/
=> nil

Si ahora lo que queremos es que no coincida, debemos utilizar la negación !~, fíjate que los resultados que son true o false, si no coincide devuelve un true y si coincide un false, vemos un ejemplo:

> «Hello regular expressions» !~ /Express/
=> true -> no la ha encontrado por eso obtenemos un true
> «Hello regular expressions» !~ /Expressions/
=> true
> «Hello regular expressions» !~ /expressions/
=> false -> en esta caso si la ha encontrado

Podríamos utilizar el método match de Ruby pasando como parámetros el string y como segundo parámetro podríamos decir que arranque la operación de comprobación desde el número x, veamos algunos ejemplos:

> my_match = /expressions/.match(string)
=> #<MatchData «expressions»>
> my_match = /expressions/.match(string,15)
=> nil
> my_match = /expressions/.match(string,10)
=> #<MatchData «expressions»>
> my_match = /expressions/.match(string,14)
=> #<MatchData «expressions»>

Si ahora si queremos cambiar nuestro string, tenemos que utilizar sub y gsub con nuestro string de entrada. La diferencia entre utilizar sub y gsub es que con sub si lo encuentra, en la primera coincidencia se detiene, si queremos continuar a pesar de haber encontrado la coincidencia, debemos utilizar gsub, veamos algunos ejemplos:

> str = «Dog and Cat»
=> «Dog and Cat»
> new_str1 = str.sub(/a/, «*»)
=> «Dog *nd Cat»
> new_str2 = str.gsub(/a/, «*»)
=> «Dog *nd C*t»

> puts «Using sub: #{new_str1}»
Using sub: Dog *nd Cat
=> nil
> puts «Using gsub: #{new_str2}»
Using gsub: Dog *nd C*t
=> nil

Ahora imagina que tenemos en nuestro string el siguiente número de teléfono y texto que queremos hacer una limpia de caracteres:

phone = «2662-3636-1245 # My Phone Number»

phone = phone.sub!(/#.*$/, «») el patrón /#.*$/ lo que hace es que buscamos la # que coincida excepto en nueva línea por el punto y además coincida 0 o más veces por el * y hasta el final de la línea por el $ y me los cambias por vacío, es decir, quita la # en todos los sitios que esté.

phone = phone.gsub!(/\D/, «») el patrón /\D/ lo que hace es que elimina todo lo que no sea un dígito \D, si lo queremos con dígitos sería \d o equivalente a [0-9]

Si ejecutamos en consola las operaciones obtenemos:

 > phone = phone.sub!(/#.*$/, «»)
=> «2662-3636-1245 »
> puts «My new Phone number is : #{phone}»
My new Phone number is : 2662-3636-1245
=> nil

> phone = phone.gsub!(/\D/, «»)
=> «266236361245»
> puts «My new Phone number is: #{phone}»
My new Phone number is: 266236361245
=> nil

La búsqueda positiva hacia delante ?= veamos un ejemplo de sustitución:

> str = «Hello regular expression» Tenemos este string original y queremos que encuentre expression y que haga el cambio por fash pero en la coincidencia de ?=ion me lo dejas en el cambio, que finalmente obtengamos fashion

 > str.gsub(/express(?=ion)/, «fash»)
=> «Hello regular fashion»

En el próximo post veremos algunos patrones algo más complejos para que podamos  ver combinaciones utilizadas en proyectos reales.

2 comentarios en “Expresiones regulares en Ruby – No te dejes intimidar – Primera parte

Replica a carlossanchezperez Cancelar la respuesta