Как мне найти строку, начинающуюся с другой строки в Ruby?

Ответы:

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

[править] Это то, чего я не знал до этого вопроса: start_withпринимает несколько аргументов.

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')
steenslag
источник
1
MRI 1.8.7 не имеет start_with?, но MRI 1.9 делает, как и Rails.
Уэйн Конрад
@Wayne Conrad: странно, 1.8.7 действительно имеет документацию для String#start_with?.
Йорг Миттаг
@ Jörg W Mittag, как ни странно, я ошибался. МРТ 1.8.7 действительно есть start_with?. Я думаю, что я опечатал это, когда я загрузил IRB, чтобы попробовать это.
Уэйн Конрад
7
Интересно, что Rails определяет грамматически правильное значение starts_with?, к которому в 1.8.7 и выше добавлен псевдоним start_with?.
Марк Томас
56

Поскольку здесь представлено несколько методов, я хотел выяснить, какой из них был самым быстрым. Используя 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

Похоже, start_with?это самый быстрый из всех.

Обновлены результаты с Ruby 2.2.2p95 и более новой машиной:

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)
hasło
источник
4
неудивительно, что компиляция и тестирование регулярных выражений намного сложнее, чем простое сравнение байтов
akostadinov
1
Следует отметить, что Regex намного лучше для поиска без учета регистра, даже если вы заранее рассчитали все варианты вариантов для тестовой строки.
Питер П.
3
@PeterP. Я только что проверил регистронезависимый поиск, и start_with? по- прежнему выходит вперед , если вы просто downcase строки для поиска , а затем сравнить с поисковой строкой строчных букв: "FooBar".downcase.start_with?("foo").
Haslo
4

Метод, упомянутый steenslag, лаконичен, и с учетом объема вопроса его следует считать правильным ответом. Однако также стоит знать, что этого можно достичь с помощью регулярного выражения, которое, если вы еще не знакомы с Ruby, является важным навыком, который необходимо изучить.

Поиграй с Rubular: http://rubular.com/

Но в этом случае следующий оператор ruby ​​вернет true, если строка слева начинается с 'abc'. Символ \ A в литерале регулярных выражений справа означает «начало строки». Поиграйте с Rubular - станет понятно, как все работает.

'abcdefg' =~  /\Aabc/ 
Pākehā
источник
Как указал Уэйн Конрад, этот метод также будет работать в более широком диапазоне времени выполнения, чем start_with.
Пакеха
2

мне нравиться

if ('string'[/^str/]) ...
жестяной человек
источник
8
Вы должны использовать [/\Astr/]здесь. Ваше регулярное выражение также соответствует "another\nstring".
Haslo