Wyrażenie Ruby% r {}

135

W modelu jest pole

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

Dla mnie wygląda to dość dziwnie. Zdaję sobie sprawę, że jest to wyrażenie regularne. Ale chciałbym:

  • wiedzieć, co to dokładnie oznacza. Jest %r{value}równe /value/?
  • móc go zastąpić zwykłym operatorem regex Ruby /some regex/lub ~=. Czy to możliwe?
Alexandre
źródło

Odpowiedzi:

262

%r{}jest odpowiednikiem /.../notacji, ale pozwala na umieszczenie znaku „/” w wyrażeniu regularnym bez konieczności jego ucieczki:

%r{/home/user}

jest równa:

/\/home\/user/

To jest tylko towar składni dla czytelności.

Edytować:

Zauważ, że zamiast „{}” możesz użyć prawie każdej pary znaków niealfabetycznych. Te warianty działają równie dobrze:

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

Edycja 2:

Zauważ, że ten %r{}xwariant ignoruje białe znaki, dzięki czemu złożone wyrażenia regularne są bardziej czytelne. Przykład z przewodnika po stylu Ruby na GitHub :

regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
Eureka
źródło
5
Głos przeciw był tylko 1 godzinę temu. Jeśli chodzi o odstęp jako ogranicznik, jest to niesamowite, ale nie jest to coś, co polecam, aby móc odczytać twój kod bez zastanawiania się sześć miesięcy później :)
Eureka
3
Jeśli jako separatora użyjesz spacji, wyrażenie regularne przestanie działać, jeśli później dodasz do niego spacje. Myślę, że chodzi o użycie ograniczników, które nie pasują do niczego w wyrażeniu regularnym, z nawiasami klamrowymi jako preferowaną wartością domyślną.
Steven Hirlston
1
To prawie tak, jakby ruby ​​został zaprojektowany do pisania tak okropnego kodu, jak to tylko możliwe
Roman
Nie rozumiem notatki swojej drugiej zmiany. Co jest takiego specjalnego %r{}x? /.../xignoruje również spacje. Nie jest to żadna specjalna właściwość %rskładni. Wszystkie opcje, które mogą nastąpić, /../mogą również nastąpić %r{}.
Mecki
9

\.=> zawiera kropkę
(gif|jpg|jpeg|png)=> wtedy jedno z tych rozszerzeń
$=> koniec, nic po nim
i=> wielkość liter nie ma znaczenia

To to samo, co pisanie /\.(gif|jpg|jpeg|png)$/i.

Samy Dindane
źródło
Czy% r {value} jest równa / value /?
Alexandre
Tak, to jest to samo. - Tak %w[1 2 3]jak [1, 2, 3]na przykład.
Samy Dindane
7
%w[1 2 3]to nie to samo co [1, 2, 3]. To jest to samo co ['1', '2', '3'].
Jörg W Mittag
@ JörgWMittag Dzięki za sprostowanie.
Samy Dindane
9

Dzięki %r, można używać żadnych ograniczników.

Można użyć %r{}lub %r[]czy %r!!itd.

Zaletą używania innych separatorów jest to, że nie musisz uciekać od /używanego w normalnym dosłownym wyrażeniu regularnym.

xdazz
źródło
3

to wyrażenie regularne pasuje do wszystkich ciągów kończących się na .gif, .jpg ...

możesz go zastąpić

/\.(gif|jpg|jpeg|png)$/i
Erez Rabih
źródło
1

Oznacza to, że image_file_namemusi kończyć się ( $) kropką i jednym z gif, jpg, jpeg lub png.

Tak, %r{}znaczy dokładnie to samo, //ale %r{}nie musisz uciekać /.

Hauleth
źródło