Como localizo se uma string começa com outra no Ruby?

Respostas:

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

[editar] Isso é algo que eu não sabia antes desta pergunta: start_withleva vários argumentos.

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')
steenslag
fonte
1
A MRI 1.8.7 não possui start_with?, mas a MRI 1.9 possui, assim como o Rails.
Wayne Conrad
@Wayne Conrad: Estranhamente, 1.8.7 faz ter a documentação String#start_with?.
Jörg W Mittag
@ Jörg W Mittag, talvez não estranhamente, eu estava errado. MRI 1.8.7 realmente tem start_with?. Acho que digitei quando carreguei o irb para experimentá-lo.
Wayne Conrad
7
Curiosamente, o Rails define o gramaticalmente correto starts_with?, que em 1.8.7 e acima é apenas um alias para start_with?.
Mark Thomas
56

Como existem vários métodos apresentados aqui, eu queria descobrir qual era o mais rápido. Usando 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

Então parece que não start_with?é o mais rápido do grupo.

Resultados atualizados com o Ruby 2.2.2p95 e uma máquina mais recente:

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
fonte
4
não é surpreendente dada a compilar e testar para expressões regulares é muito mais difícil, então, simplesmente comparando bytes
akostadinov
1
Deve-se observar que o Regex é muito superior para pesquisas sem distinção entre maiúsculas e minúsculas, mesmo se você tiver calculado todas as permutações de casos para a sequência de testes com antecedência.
Peter P.
3
@PeterP. Acabei de testar pesquisas que não diferenciam maiúsculas de minúsculas e start_with? ainda sai na frente se você apenas downcase a string de pesquisa e, em seguida, comparar com a seqüência de pesquisa em minúsculas: "FooBar".downcase.start_with?("foo").
haslo 4/16
4

O método mencionado por steenslag é conciso e, dado o escopo da pergunta, deve ser considerada a resposta correta. No entanto, também vale a pena saber que isso pode ser alcançado com uma expressão regular, que, se você ainda não está familiarizado com Ruby, é uma habilidade importante para aprender.

Jogue com Rubular: http://rubular.com/

Mas, neste caso, a seguinte instrução ruby ​​retornará true se a string à esquerda começar com 'abc'. O \ A no literal da regex à direita significa 'o início da string'. Brinque com a rubular - ficará claro como as coisas funcionam.

'abcdefg' =~  /\Aabc/ 
pakeha
fonte
Conforme apontado por Wayne Conrad, esse método também funcionará em uma variedade maior de tempos de execução do que o start_with.
pakeha
2

Eu gosto

if ('string'[/^str/]) ...
o homem de lata
fonte
8
Você deveria estar usando [/\Astr/]aqui. Sua regex também corresponde "another\nstring".
haslo