Bagaimana saya menemukan jika sebuah string dimulai dengan string lain di Ruby?

Jawaban:

254
puts 'abcdefg'.start_with?('abc')  #=> true

[Sunting] Ini adalah sesuatu yang saya tidak tahu sebelum pertanyaan ini: start_withmengambil beberapa argumen.

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')
steenslag
sumber
1
MRI 1.8.7 tidak memiliki start_with?, tetapi MRI 1.9 tidak, seperti halnya Rails.
Wayne Conrad
@Wayne Conrad: Anehnya, 1.8.7 memang memiliki dokumentasi untuk String#start_with?.
Jörg W Mittag
@ Jorg W Mittag, mungkin tidak aneh, saya salah. MRI 1.8.7 memang memiliki start_with?. Saya rasa saya salah ketik ketika saya memuat irb untuk mencobanya.
Wayne Conrad
7
Menariknya, Rails mendefinisikan tata bahasa yang benar starts_with?, yang dalam 1.8.7 dan di atas hanya alias start_with?.
Mark Thomas
56

Karena ada beberapa metode yang disajikan di sini, saya ingin mencari tahu mana yang tercepat. Menggunakan Ruby 1.9.3p362:

irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> Benchmark.realtime { 1.upto(10000000) { "foobar"[/\Afoo/] }}
=> 12.477248
irb(main):003:0> Benchmark.realtime { 1.upto(10000000) { "foobar" =~ /\Afoo/ }}
=> 9.593959
irb(main):004:0> Benchmark.realtime { 1.upto(10000000) { "foobar"["foo"] }}
=> 9.086909
irb(main):005:0> Benchmark.realtime { 1.upto(10000000) { "foobar".start_with?("foo") }}
=> 6.973697

Jadi sepertinya itu start_with?yang tercepat dari kelompok itu.

Hasil yang diperbarui dengan Ruby 2.2.2p95 dan mesin yang lebih baru:

require 'benchmark'
Benchmark.bm do |x|
  x.report('regex[]')    { 10000000.times { "foobar"[/\Afoo/] }}
  x.report('regex')      { 10000000.times { "foobar" =~ /\Afoo/ }}
  x.report('[]')         { 10000000.times { "foobar"["foo"] }}
  x.report('start_with') { 10000000.times { "foobar".start_with?("foo") }}
end

            user       system     total       real
regex[]     4.020000   0.000000   4.020000 (  4.024469)
regex       3.160000   0.000000   3.160000 (  3.159543)
[]          2.930000   0.000000   2.930000 (  2.931889)
start_with  2.010000   0.000000   2.010000 (  2.008162)
haslo
sumber
4
tidak mengherankan mengingat kompilasi dan pengujian untuk ekspresi reguler jauh lebih sulit daripada hanya membandingkan byte
akostadinov
1
Perlu dicatat bahwa Regex jauh lebih unggul untuk pencarian case-sensitive, bahkan jika Anda menghitung semua permutasi case untuk string uji sebelumnya.
Peter P.
3
@PeterP. Saya baru saja menguji pencarian yang tidak peka terhadap huruf besar-kecil, dan mulai_dengan? masih keluar ke depan jika Anda hanya downcase string untuk mencari dan kemudian membandingkan dengan huruf kecil string pencarian: "FooBar".downcase.start_with?("foo").
haslo
4

Metode yang disebutkan oleh steenslag sangat singkat, dan dengan lingkup pertanyaan itu harus dianggap jawaban yang benar. Namun perlu juga diketahui bahwa ini dapat dicapai dengan ekspresi reguler, yang jika Anda belum terbiasa dengan Ruby, adalah keterampilan penting untuk dipelajari.

Selamat bermain dengan Rubular: http://rubular.com/

Tetapi dalam kasus ini, pernyataan ruby ​​berikut akan mengembalikan true jika string di sebelah kiri dimulai dengan 'abc'. The \ A dalam regex literal di sebelah kanan berarti 'awal dari string'. Bermainlah dengan rubular - akan menjadi jelas bagaimana segala sesuatu bekerja.

'abcdefg' =~  /\Aabc/ 
pakeha
sumber
Seperti yang ditunjukkan oleh Wayne Conrad, metode ini juga akan bekerja pada variasi runtime yang lebih luas daripada start_with.
pakeha
2

saya suka

if ('string'[/^str/]) ...
Manusia Timah
sumber
8
Anda harus menggunakannya di [/\Astr/]sini. Regex Anda juga cocok "another\nstring".
haslo