Как узнать, начинается ли строка с другой строки в Ruby?

Как лучше всего узнать, начинается ли строка с другой в Ruby (без рельсов)?


person Guillaume Coté    schedule 12.11.2010    source источник
comment
См. stackoverflow.com/questions/4130364.   -  person Nakilon    schedule 12.11.2010


Ответы (4)


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

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

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')
person steenslag    schedule 12.11.2010
comment
В MRI 1.8.7 нет start_with?, но есть в MRI 1.9, как и в Rails. - person Wayne Conrad; 13.11.2010
comment
@Wayne Conrad: Как ни странно, в 1.8.7 есть документация для String#start_with?. - person Jörg W Mittag; 13.11.2010
comment
@ Jörg W Mittag, возможно, не странно, я был неправ. В MRI 1.8.7 действительно есть start_with?. Думаю, я опечатался, когда загрузил irb, чтобы попробовать. - person Wayne Conrad; 13.11.2010
comment
Интересно, что Rails определяет грамматически правильное starts_with?, которое в 1.8.7 и выше просто имеет псевдоним start_with?. - person Mark Thomas; 13.11.2010

Поскольку здесь представлено несколько методов, я хотел выяснить, какой из них был самым быстрым. Использование Руби 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)
person haslo    schedule 11.01.2013
comment
неудивительно, учитывая, что компиляция и тестирование регулярных выражений намного сложнее, чем простое сравнение байтов - person akostadinov; 05.11.2014
comment
Следует отметить, что Regex намного лучше подходит для поиска без учета регистра, даже если вы заранее вычислили все перестановки случаев для тестовой строки. - person Peter P.; 03.04.2015
comment
@ПитерП. Я только что проверил поиск без учета регистра, и start_with? все еще выходит вперед, если вы просто прописываете строку для поиска, а затем сравниваете со строкой поиска в нижнем регистре: "FooBar".downcase.start_with?("foo"). - person haslo; 04.05.2016

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

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

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

'abcdefg' =~  /\Aabc/ 
person pakeha    schedule 12.11.2010
comment
Как указал Уэйн Конрад, этот метод также будет работать в более широком диапазоне сред выполнения, чем start_with. - person pakeha; 13.11.2010

мне нравится

if ('string'[/^str/]) ...
person the Tin Man    schedule 12.11.2010
comment
Вы должны использовать [/\Astr/] здесь. Ваше регулярное выражение также соответствует "another\nstring". - person haslo; 11.01.2013