L'expression Ruby% r {}

131

Dans un modèle, il y a un champ

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

Cela me semble assez étrange. Je suis conscient qu'il s'agit d'une expression régulière. Mais je voudrais:

  • pour savoir ce que cela signifie exactement. Est%r{value} égal à /value/?
  • être en mesure de le remplacer par l'opérateur normal de regex Ruby /some regex/ou ~=. C'est possible?
Alexandre
la source

Réponses:

254

%r{}équivaut à la /.../notation, mais vous permet d'avoir '/' dans votre expression rationnelle sans avoir à les échapper:

%r{/home/user}

est équivalent à:

/\/home\/user/

Ce n'est qu'une commodité de syntaxe, pour la lisibilité.

Éditer:

Notez que vous pouvez utiliser presque n'importe quelle paire de caractères non alphabétiques au lieu de «{}». Ces variantes fonctionnent aussi bien:

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

Modifier 2:

Notez que la %r{}xvariante ignore les espaces, ce qui rend les expressions rationnelles complexes plus lisibles. Exemple du guide de style Ruby de GitHub :

regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
Eurêka
la source
5
Le vote défavorable remonte à 1 heure seulement. Quant à l'espace comme délimiteur, c'est génial, mais pas le genre de chose que je recommanderai pour pouvoir lire votre code sans être perplexe six mois plus tard :)
Eureka
3
Si vous utilisez des espaces comme séparateur, votre expression régulière sera interrompue si vous y ajoutez des espaces ultérieurement. Je pense que l'idée est d'utiliser des délimiteurs qui ne correspondent à rien dans votre expression régulière, avec des accolades par défaut.
Steven Hirlston
1
C'est presque comme si ruby ​​était conçu pour écrire un code aussi horrible que possible
Roman
Je ne comprends pas la note de votre deuxième modification. Quelle est la particularité %r{}x? /.../xignore également les espaces. Ce n'est pas une propriété spéciale de la %rsyntaxe. Toutes les options qui peuvent suivre /../peuvent également suivre %r{}.
Mecki
9

\.=> contient un point
(gif|jpg|jpeg|png)=> alors, soit l'une de ces extensions
$=> la fin, rien après
i=> insensible à la casse

Et c'est la même chose que l'écriture /\.(gif|jpg|jpeg|png)$/i.

Samy Dindane
la source
% R {value} est-il égal à / value /?
Alexandre le
Oui, c'est pareil. - Comme %w[1 2 3]c'est le même que [1, 2, 3]par exemple.
Samy Dindane
6
%w[1 2 3]n'est pas la même chose que [1, 2, 3]. C'est la même chose que ['1', '2', '3'].
Jörg W Mittag
@ JörgWMittag Merci pour la rectification.
Samy Dindane
9

Avec %r, vous pouvez utiliser n'importe quel délimiteur.

Vous pouvez utiliser %r{}ou %r[]ou %r!!etc.

L'avantage d'utiliser d'autres délimiteurs est que vous n'avez pas besoin d'échapper au /littéral utilisé dans une expression régulière normale.

xdazz
la source
3

cette expression rationnelle correspond à toutes les chaînes qui se terminent par .gif, .jpg ...

tu pourrais le remplacer par

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

Cela signifie que cela image_file_namedoit se terminer ($ ) par un point et l'un des formats gif, jpg, jpeg ou png.

Oui %r{}signifie exactement la même chose que //mais en %r{}vous n'avez pas besoin de vous échapper /.

Hauleth
la source