Выражение Ruby% r {}

131

В модели есть поле

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

Для меня это выглядит довольно странно. Я знаю, что это регулярное выражение. Но я бы хотел:

  • чтобы знать, что именно это означает. Является ли %r{value}равно /value/?
  • иметь возможность заменить его обычным оператором регулярного выражения Ruby /some regex/или ~=. Является ли это возможным?
Александр
источник

Ответы:

254

%r{}эквивалентно /.../обозначению, но позволяет вам иметь '/' в вашем регулярном выражении, не экранируя их:

%r{/home/user}

эквивалентно:

/\/home\/user/

Это только синтаксис для удобства чтения.

Редактировать:

Обратите внимание, что вы можете использовать почти любую неалфавитную пару символов вместо '{}'. Эти варианты тоже работают:

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

Изменить 2:

Обратите внимание, что этот %r{}xвариант игнорирует пробелы, что делает сложные регулярные выражения более удобочитаемыми. Пример из руководства по стилю Ruby на GitHub :

regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
эврика
источник
5
Голос против был только 1 час назад. Что касается пробела в качестве разделителя, это круто, но я не рекомендую его, чтобы иметь возможность читать ваш код без недоумения шесть месяцев спустя :)
Eureka
3
Если вы используете пробелы в качестве разделителя, ваше регулярное выражение сломается, если вы добавите к нему пробелы позже. Я думаю, идея состоит в том, чтобы использовать разделители, которые не соответствуют чему-либо в вашем регулярном выражении, с фигурными скобками в качестве предпочтительного значения по умолчанию.
Стивен Хирлстон
1
Это похоже на то, как если бы Ruby был разработан для написания настолько ужасного кода, насколько это возможно,
Роман
Не понимаю примечания к вашему второму редактированию. Что особенного %r{}x? /.../xтакже игнорирует пробелы. Это не особенное свойство %rсинтаксиса. Все варианты, которые могут последовать, /../также могут следовать %r{}.
Mecki
9

\.=> содержит точку
(gif|jpg|jpeg|png)=> тогда любое из этих расширений
$=> конец, ничего после него
i=> регистр не учитывается

И это то же самое, что писать /\.(gif|jpg|jpeg|png)$/i.

Сами Диндан
источник
% R {значение} равно / значение /?
Alexandre
Да, это то же самое. - Так %w[1 2 3]же, как [1, 2, 3]например.
Samy Dindane
6
%w[1 2 3]это не то же самое, что [1, 2, 3]. Это так же, как ['1', '2', '3'].
Jörg W Mittag
@ JörgWMittag Спасибо за исправление.
Samy Dindane,
9

С %r, вы можете использовать любые разделители.

Вы можете использовать %r{}или %r[]или %r!!т. Д.

Преимущество использования других разделителей заключается в том, что вам не нужно избегать /использования обычного литерала регулярного выражения.

xdazz
источник
3

это регулярное выражение соответствует всем строкам, которые заканчиваются на .gif, .jpg ...

вы можете заменить его

/\.(gif|jpg|jpeg|png)$/i
Эрез Рабих
источник
1

Это означает, что в image_file_nameконце ( $) должна стоять точка и одно из значений gif, jpg, jpeg или png.

Да %r{}означает то же самое, //но в %r{}тебе не нужно убегать /.

Hauleth
источник