Ekspresi Ruby% r {}

131

Dalam model ada bidang

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

Terlihat aneh bagi saya. Saya sadar bahwa ini adalah ekspresi reguler. Tapi saya ingin:

  • untuk mengetahui apa artinya sebenarnya. Apakah %r{value}sama dengan /value/?
  • dapat menggantinya dengan operator regex Ruby normal /some regex/atau ~=. Apa itu mungkin?
Alexandre
sumber

Jawaban:

254

%r{}setara dengan /.../notasi, tetapi memungkinkan Anda untuk memiliki '/' di regexp Anda tanpa harus menghindarinya:

%r{/home/user}

setara dengan:

/\/home\/user/

Ini hanya komoditas sintaksis, untuk keterbacaan.

Edit:

Perhatikan bahwa Anda dapat menggunakan hampir semua pasangan karakter non-alfabet alih-alih '{}'. Varian ini juga berfungsi:

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

Edit 2:

Perhatikan bahwa %r{}xvarian mengabaikan spasi putih, membuat regexps kompleks lebih mudah dibaca. Contoh dari panduan gaya Ruby GitHub :

regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
Eureka
sumber
5
Downvote hanya 1 jam yang lalu. Adapun ruang sebagai pembatas, ini luar biasa, tetapi bukan hal yang saya akan sarankan untuk dapat membaca kode Anda tanpa menjadi bingung enam bulan kemudian :)
Eureka
3
Jika Anda menggunakan spasi sebagai pembatas Anda, ekspresi reguler Anda akan pecah jika Anda menambahkan spasi ke nanti. Saya pikir idenya adalah menggunakan pembatas yang tidak cocok dengan apa pun dalam ekspresi reguler Anda, dengan kurung kurawal sebagai default yang disukai.
Steven Hirlston
1
Hampir seolah-olah ruby ​​dirancang untuk menulis kode mengerikan mungkin
Roman
Tidak mengerti catatan edit kedua Anda. Apa yang spesial %r{}x? /.../xjuga mengabaikan spasi putih. Ini bukan properti %rsintaksis khusus. Semua opsi yang bisa diikuti /../juga bisa mengikuti %r{}.
Mecki
9

\.=> mengandung titik
(gif|jpg|jpeg|png)=> lalu, salah satu dari ekstensi ini
$=> akhirnya, tidak ada setelahnya
i => case-sensitive

Dan itu sama dengan menulis /\.(gif|jpg|jpeg|png)$/i.

Samy Dindane
sumber
Apakah% r {value} sama dengan / value /?
Alexandre
Ya, sama saja. - Seperti %w[1 2 3]sama dengan [1, 2, 3]misalnya.
Samy Dindane
6
%w[1 2 3]adalah tidak sama dengan [1, 2, 3]. Itu sama dengan ['1', '2', '3'].
Jörg W Mittag
@ JörgWMittag Terima kasih atas perbaikannya.
Samy Dindane
9

Dengan %r, Anda bisa menggunakan pembatas apa pun.

Anda bisa menggunakan %r{}atau %r[]atau lainnya %r!!.

Manfaat menggunakan pembatas lain adalah Anda tidak perlu melarikan diri dari yang /digunakan dalam regex literal normal.

xdazz
sumber
3

regexp ini cocok dengan semua string yang diakhiri dengan .gif, .jpg ...

Anda bisa menggantinya dengan

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

Ini berarti bahwa image_file_nameharus diakhiri ( $) dengan titik dan salah satu dari gif, jpg, jpeg atau png.

Ya %r{}berarti persis sama //tetapi di dalam %r{}kamu tidak perlu melarikan diri /.

Hauleth
sumber