¿Cómo encuentro si una cadena comienza con otra cadena en Ruby?

Respuestas:

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

[editar] Esto es algo que no sabía antes de esta pregunta: start_withtoma múltiples argumentos.

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')
steenslag
fuente
1
MRI 1.8.7 no tiene start_with?, pero MRI 1.9 sí, al igual que Rails.
Wayne Conrad el
@Wayne Conrad: Extrañamente, 1.8.7 hace tener la documentación String#start_with?.
Jörg W Mittag el
@ Jörg W Mittag, tal vez no sea extraño, me equivoqué. MRI 1.8.7 sí tiene start_with?. Supongo que lo escribí cuando cargué irb para probarlo.
Wayne Conrad el
77
Curiosamente, Rails define la gramática correcta starts_with?, que en 1.8.7 y superior solo tiene un alias start_with?.
Mark Thomas el
56

Dado que aquí se presentan varios métodos, quería averiguar cuál era el más 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

Parece que start_with?es el más rápido del grupo.

Resultados actualizados con Ruby 2.2.2p95 y una máquina más nueva:

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
fuente
44
no es sorprendente dado que compilar y probar expresiones regulares es mucho más difícil que simplemente comparar bytes
akostadinov
1
Cabe señalar que Regex es muy superior para las búsquedas que no distinguen entre mayúsculas y minúsculas, incluso si calculó todas las permutaciones de casos para la cadena de prueba con anticipación.
Peter P.
3
@PeterP. Acabo de probar búsquedas que no distinguen entre mayúsculas y minúsculas, y start_with? todavía sale adelante si sólo downcase la cadena a buscar y luego comparar con la cadena de búsqueda en minúsculas: "FooBar".downcase.start_with?("foo").
haslo
4

El método mencionado por steenslag es breve y, dado el alcance de la pregunta, debe considerarse la respuesta correcta. Sin embargo, también vale la pena saber que esto se puede lograr con una expresión regular, que si no está familiarizado con Ruby, es una habilidad importante para aprender.

Juega con Rubular: http://rubular.com/

Pero en este caso, la siguiente declaración de ruby ​​devolverá verdadero si la cadena de la izquierda comienza con 'abc'. La \ A en el literal regex a la derecha significa 'el comienzo de la cadena'. Juegue con el rubular: quedará claro cómo funcionan las cosas.

'abcdefg' =~  /\Aabc/ 
pakeha
fuente
Como señaló Wayne Conrad, este método también funcionará en una variedad más amplia de tiempos de ejecución que start_with will.
pakeha
2

me gusta

if ('string'[/^str/]) ...
el hombre de hojalata
fuente
8
Deberías estar usando [/\Astr/]aquí. Tu expresión regular también coincide "another\nstring".
haslo