A expressão Ruby% r {}

131

Em um modelo, há um campo

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

Parece muito estranho para mim. Estou ciente de que esta é uma expressão regular. Mas eu gostaria:

  • para saber exatamente o que isso significa. É %r{value}igual a /value/?
  • poder substituí-lo pelo operador normal de regex Ruby /some regex/ou ~=. É possível?
Alexandre
fonte

Respostas:

254

%r{}é equivalente à /.../notação, mas permite que você tenha '/' no seu regexp sem precisar escapar deles:

%r{/home/user}

é equivalente a:

/\/home\/user/

Esta é apenas uma mercadoria de sintaxe, para legibilidade.

Editar:

Observe que você pode usar quase qualquer par de caracteres não alfabéticos em vez de '{}'. Essas variantes também funcionam:

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

Edição 2:

Observe que a %r{}xvariante ignora o espaço em branco, tornando regexps complexos mais legíveis. Exemplo do guia de estilo Ruby do GitHub :

regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
Eureka
fonte
5
O voto negativo foi de apenas 1 hora atrás. Quanto ao espaço como delimitador, isso é incrível, mas não o tipo de coisa que eu vou recommand para ser capaz de ler o seu código sem beeing intrigado seis meses mais tarde :)
Eureka
3
Se você usar espaços como seu delimitador, sua expressão regular será interrompida se você adicionar espaços a ele mais tarde. Acho que a ideia é usar delimitadores que não correspondam a nada na sua expressão regular, com chaves como o padrão preferido.
Steven Hirlston
1
É quase como se ruby foi projetado para escrever como código horrível quanto possível
Roman
Não entenda a nota da sua segunda edição. O que é especial %r{}x? /.../xtambém ignora o espaço em branco. Esta não é uma propriedade especial da %rsintaxe. Todas as opções que podem ser seguidas /../também podem ser seguidas %r{}.
Mecki
9

\.=> contém um ponto
(gif|jpg|jpeg|png)=> então, qualquer uma dessas extensões
$=> o fim, nada depois
i=> não faz distinção entre maiúsculas e minúsculas

E é o mesmo que escrever /\.(gif|jpg|jpeg|png)$/i.

Samy Dindane
fonte
% R {value} é igual a / value /?
Alexandre
Sim, é a mesma coisa. - Como %w[1 2 3]é o mesmo que [1, 2, 3]por exemplo.
Samy Dindane 12/09
6
%w[1 2 3]não é o mesmo que [1, 2, 3]. É o mesmo que ['1', '2', '3'].
Jörg W Mittag
@ JörgWMittag Obrigado pela retificação.
Samy Dindane
9

Com %r, você pode usar qualquer delimitador.

Você poderia usar %r{}ou %r[]ou %r!!etc.

A vantagem de usar outros delímetros é que você não precisa escapar do /usado no literal regex normal.

xdazz
fonte
3

esse regexp corresponde a todas as strings que terminam com .gif, .jpg ...

você poderia substituí-lo por

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

Isso significa que image_file_namedeve terminar ( $) com ponto e um de gif, jpg, jpeg ou png.

Sim %r{}significa exatamente o mesmo que //mas %r{}você não precisa escapar /.

Hauleth
fonte