Làm cách nào để tìm chuỗi nếu một chuỗi bắt đầu bằng một chuỗi khác trong Ruby?


Câu trả lời:


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

[sửa] Đây là điều tôi chưa biết trước câu hỏi này: start_withcó nhiều đối số.

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')

1
MRI 1.8.7 không có start_with?, nhưng MRI 1.9 cũng vậy, cũng như Rails.
Wayne Conrad

@Wayne Conrad: Thật kỳ lạ, 1.8.7 không có tài liệu cho String#start_with?.
Jörg W Mittag

@ Jorg W Mittag, có lẽ không lạ, tôi đã nhầm. MRI 1.8.7 thực sự có start_with?. Tôi đoán tôi đã đánh máy nó khi tôi tải lên irb để thử nó.
Wayne Conrad

7
Thật thú vị, Rails định nghĩa chính xác ngữ pháp starts_with?, trong phiên bản 1.8.7 trở lên chỉ là bí danh start_with?.
Mark Thomas

56

Vì có một số phương pháp được trình bày ở đây, tôi muốn tìm ra phương pháp nào nhanh nhất. Sử dụng 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

Vì vậy, nó trông giống như start_with?ist nhanh nhất của bó.

Kết quả được cập nhật với Ruby 2.2.2p95 và một máy mới hơn:

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)

4
không có gì đáng ngạc nhiên khi biên dịch và kiểm tra các biểu thức thông thường khó hơn nhiều so với việc so sánh các byte
akostadinov

1
Cần lưu ý rằng Regex vượt trội hơn nhiều đối với các tìm kiếm không phân biệt chữ hoa chữ thường, ngay cả khi bạn đã tính toán tất cả các hoán vị của các trường hợp cho chuỗi thử nghiệm trước thời hạn.
Peter P.

3
@PeterP. Tôi vừa thử nghiệm các tìm kiếm không phân biệt chữ hoa chữ thường và start_with? vẫn đi ra phía trước nếu bạn chỉ viết thường chuỗi tìm kiếm và sau đó so sánh với chuỗi tìm kiếm chữ thường : "FooBar".downcase.start_with?("foo").
haslo

4

Phương pháp được đề cập bởi steenslag là ngắn gọn, và đưa ra phạm vi của câu hỏi nên được coi là câu trả lời đúng. Tuy nhiên, cũng đáng để biết rằng điều này có thể đạt được bằng một biểu thức chính quy, mà nếu bạn chưa quen thuộc với Ruby, là một kỹ năng quan trọng cần học.

Chơi với Rubular: http://rubular.com/

Nhưng trong trường hợp này, câu lệnh ruby ​​sau sẽ trả về true nếu chuỗi bên trái bắt đầu bằng 'abc'. \ A trong regex nghĩa đen bên phải có nghĩa là 'bắt đầu của chuỗi'. Có một trò chơi với rubular - nó sẽ trở nên rõ ràng cách mọi thứ hoạt động.

'abcdefg' =~  /\Aabc/ 

Như Wayne Conrad đã chỉ ra, phương pháp này cũng sẽ hoạt động trên nhiều thời gian chạy hơn so với start_with.
pakeha

2

tôi thích

if ('string'[/^str/]) ...

8
Bạn nên sử dụng [/\Astr/]ở đây. Regex của bạn cũng phù hợp "another\nstring".
haslo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.