How do I find if a string starts with another string in Ruby?
Asked Answered
B

4

193

What the best way to find if a string starts with another in Ruby (without rails)?

Baer answered 12/11, 2010 at 19:57 Comment(1)
See stackoverflow.com/questions/4130364Jilli
E
307
puts 'abcdefg'.start_with?('abc')  #=> true

[edit] This is something I didn't know before this question: start_with? takes multiple arguments.

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')
Ephedrine answered 12/11, 2010 at 20:2 Comment(4)
MRI 1.8.7 does not have start_with?, but MRI 1.9 does, as does Rails.Calefactory
@Wayne Conrad: Strangely, 1.8.7 does have the documentation for String#start_with?.Backset
@Jörg W Mittag, perhaps not strangely, I was wrong. MRI 1.8.7 does indeed have start_with?. I guess I typo'd it when I loaded up irb to try it.Calefactory
Interestingly, Rails defines the grammaticaly correct starts_with?, which in 1.8.7 and above is just aliased to start_with?.Topography
P
65

Since there are several methods presented here, I wanted to figure out which one was fastest. Using 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

So it looks like start_with? ist the fastest of the bunch.

Updated results with Ruby 2.2.2p95 and a newer machine:

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)
Patinated answered 11/1, 2013 at 9:55 Comment(3)
not surprising given compiling and testing for regular expressions is much harder then simply comparing bytesLipsey
It should be noted that Regex is far superior for case insensitive searches, even if you calculated all the permutations of cases for the test string ahead of time.Arabesque
@PeterP. I just tested case insensitive searches, and start_with? still comes out ahead if you just downcase the string to search and then compare with the lowercase search string: "FooBar".downcase.start_with?("foo").Patinated
C
5

The method mentioned by steenslag is terse, and given the scope of the question it should be considered the correct answer. However it is also worth knowing that this can be achieved with a regular expression, which if you aren't already familiar with in Ruby, is an important skill to learn.

Have a play with Rubular: http://rubular.com/

But in this case, the following ruby statement will return true if the string on the left starts with 'abc'. The \A in the regex literal on the right means 'the beginning of the string'. Have a play with rubular - it will become clear how things work.

'abcdefg' =~  /\Aabc/ 
Crotchet answered 12/11, 2010 at 20:20 Comment(1)
As pointed out by Wayne Conrad, this method will also work on a wider variety of runtimes than start_with will.Crotchet
C
2

I like

if ('string'[/^str/]) ...
Cilurzo answered 12/11, 2010 at 23:19 Comment(1)
You should be using [/\Astr/] here. Your regex also matches "another\nstring".Patinated

© 2022 - 2024 — McMap. All rights reserved.