La expresión Ruby% r {}

131

En un modelo hay un campo

validates :image_file_name, :format => { :with => %r{\.(gif|jpg|jpeg|png)$}i

Se ve bastante extraño para mí. Soy consciente de que esta es una expresión regular. Pero me gustaría:

  • para saber exactamente lo que significa. Es %r{value}igual a /value/?
  • ser capaz de reemplazarlo con el operador normal de Ruby regex /some regex/o ~=. ¿Es posible?
Alexandre
fuente

Respuestas:

254

%r{}es equivalente a la /.../notación, pero le permite tener '/' en su expresión regular sin tener que escapar de ellos:

%r{/home/user}

es equivalente a:

/\/home\/user/

Esto es solo un producto de sintaxis, por legibilidad.

Editar:

Tenga en cuenta que puede usar casi cualquier par de caracteres no alfabéticos en lugar de '{}'. Estas variantes funcionan igual de bien:

%r!/home/user!
%r'/home/user'
%r(/home/user)

Edición 2:

Tenga en cuenta que la %r{}xvariante ignora los espacios en blanco, lo que hace que las expresiones regulares complejas sean más legibles. Ejemplo de la guía de estilo Ruby de GitHub :

regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
Eureka
fuente
55
El voto negativo fue hace solo 1 hora. En cuanto al espacio como delimitador, esto es increíble, pero no es el tipo de cosas que recomendaré para poder leer su código sin quedar perplejo seis meses después :)
Eureka
3
Si usa espacios como delimitador, su expresión regular se romperá si le agrega espacios más tarde. Creo que la idea es usar delimitadores que no coincidan con nada en su expresión regular, con llaves entre los valores predeterminados preferidos.
Steven Hirlston
1
Es casi como si Ruby estuviera diseñado para escribir el código más horrible posible
Roman
No entiendo la nota de tu segunda edición. ¿Qué tiene de especial %r{}x? /.../xTambién ignora los espacios en blanco. Esta no es una propiedad especial de la %rsintaxis. Todas las opciones que pueden seguir /../también pueden seguir %r{}.
Mecki
9

\.=> contiene un punto
(gif|jpg|jpeg|png)=> entonces, cualquiera de estas extensiones
$=> el final, nada después
i= = mayúsculas y minúsculas

Y es lo mismo que escribir /\.(gif|jpg|jpeg|png)$/i.

Samy Dindane
fuente
¿Es% r {value} igual a / value /?
Alexandre
Si, es lo mismo. - Como %w[1 2 3]es lo mismo que [1, 2, 3]por ejemplo.
Samy Dindane
66
%w[1 2 3]es no lo mismo que [1, 2, 3]. Es lo mismo que ['1', '2', '3'].
Jörg W Mittag el
@ JörgWMittag Gracias por la rectificación.
Samy Dindane
9

Con %r, puedes usar cualquier delimitador.

Podrías usar %r{}o %r[]o %r!!etc.

El beneficio de usar otros delimitadores es que no necesita escapar del /usado en el literal regex normal.

xdazz
fuente
3

Esta expresión regular coincide con todas las cadenas que terminan en .gif, .jpg ...

podrías reemplazarlo con

/\.(gif|jpg|jpeg|png)$/i
Erez Rabih
fuente
1

Significa que image_file_namedebe terminar ( $) con punto y uno de gif, jpg, jpeg o png.

Sí, %r{}significa exactamente lo mismo, //pero %r{}no necesitas escapar /.

Hauleth
fuente