如何在Ruby中查找一个字符串是否以另一个字符串开头?

189

在Ruby(不使用Rails)中查找字符串是否以另一个字符串开头的最佳方式是什么?


请参见 https://dev59.com/i2855IYBdhLWcg3wz33o。 - Nakilon
4个回答

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

[编辑] 在回答这个问题之前我不知道的一件事是:start_with? 可以接受多个参数。

'abcdefg'.start_with?( 'xyz', 'opq', 'ab')

1
MRI 1.8.7 没有 start_with? 方法,但是 MRI 1.9 和 Rails 都有。 - Wayne Conrad
@Wayne Conrad:奇怪的是,1.8.7版本确实有关于String#start_with?的文档。 - Jörg W Mittag
@Jörg W Mittag,也许不奇怪,我错了。MRI 1.8.7确实有start_with?。我猜我在加载irb尝试时打错了。 - Wayne Conrad
9
有趣的是,Rails 定义了语法上正确的 starts_with? 方法,在 1.8.7 及以上版本中它被别名为 start_with? - Mark Thomas

64

因为在这里提出了几种方法,我想弄清哪一种是最快的。使用 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)

4
由于编译和测试正则表达式比仅比较字节要困难得多,因此这并不奇怪。 - akostadinov
1
需要注意的是,正则表达式在不区分大小写的搜索方面要优于其他方法,即使您提前计算了测试字符串的所有大小写排列组合。 - Peter P.
4
@PeterP. 我刚测试了不区分大小写的搜索,使用start_with?函数仍然是最佳选择,只需将要搜索的字符串转换成小写字母后再与小写字母的搜索字符串进行比较即可:"FooBar".downcase.start_with?("foo") - haslo

5
steenslag提到的方法简洁明了,根据问题的范围,应该被认为是正确答案。不过,也值得知道可以用正则表达式来实现,如果你在Ruby中还不熟悉它,那就是一个重要的技能需要学习。
可以使用Rubular进行尝试:http://rubular.com/ 但在这种情况下,以下的Ruby语句将返回true,如果左边的字符串以'abc'开头,则右边的正则表达式字面值中的\A表示“字符串的开始”。可以在rubular上尝试一下-事情会变得清晰明了。
'abcdefg' =~  /\Aabc/ 

正如Wayne Conrad所指出的那样,这种方法也适用于比start_with更广泛的运行时。 - pakeha

2

I like

if ('string'[/^str/]) ...

9
你应该在这里使用 [/\Astr/]。你的正则表达式也匹配了 "another\nstring" - haslo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接