从字符串中删除第一个字符的最简单方法是什么?

Nul*_*uli 171 ruby string

例:

[12,23,987,43
Run Code Online (Sandbox Code Playgroud)

删除" [" 的最快,最有效的方法是什么,使用可能是chop()第一个字符?

Jas*_*irk 283

类似于上面的Pablo的回答,但更清洁:

str[1..-1]
Run Code Online (Sandbox Code Playgroud)

将数组从1返回到最后一个字符.

'Hello World'[1..-1]
 => "ello World"
Run Code Online (Sandbox Code Playgroud)

  • +1看一下我在答案中添加的基准测试结果.你有最快的运行时间,而且我认为它非常干净. (13认同)
  • 很好的解决方案.顺便说一句,如果想要删除第一个和最后一个字符:`str [1 ..- 2]` (4认同)

the*_*Man 225

我喜欢使用类似的东西:

asdf = "[12,23,987,43"
asdf[0] = '' 

p asdf
# >> "12,23,987,43"

我一直在寻找最快,最易读的做事方式:

require 'benchmark'

N = 1_000_000

puts RUBY_VERSION

STR = "[12,23,987,43"

Benchmark.bm(7) do |b|
  b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
  b.report('sub') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }

  b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
  b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
  b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
  b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }

end
Run Code Online (Sandbox Code Playgroud)

在我的Mac Pro上运行:

1.9.3
              user     system      total        real
[0]       0.840000   0.000000   0.840000 (  0.847496)
sub       1.960000   0.010000   1.970000 (  1.962767)
gsub      4.350000   0.020000   4.370000 (  4.372801)
[1..-1]   0.710000   0.000000   0.710000 (  0.713366)
slice     1.020000   0.000000   1.020000 (  1.020336)
length    1.160000   0.000000   1.160000 (  1.157882)
Run Code Online (Sandbox Code Playgroud)

更新以包含一个建议的答案:

require 'benchmark'

N = 1_000_000

class String
  def eat!(how_many = 1)
    self.replace self[how_many..-1]
  end

  def first(how_many = 1)
    self[0...how_many]
  end

  def shift(how_many = 1)
    shifted = first(how_many)
    self.replace self[how_many..-1]
    shifted
  end
  alias_method :shift!, :shift
end

class Array
  def eat!(how_many = 1)
    self.replace self[how_many..-1]
  end
end

puts RUBY_VERSION

STR = "[12,23,987,43"

Benchmark.bm(7) do |b|
  b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
  b.report('sub') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }

  b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
  b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
  b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
  b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
  b.report('eat!') { N.times { "[12,23,987,43".eat! } }
  b.report('reverse') { N.times { "[12,23,987,43".reverse.chop.reverse } }
end
Run Code Online (Sandbox Code Playgroud)

结果如下:

2.1.2
              user     system      total        real
[0]       0.300000   0.000000   0.300000 (  0.295054)
sub       0.630000   0.000000   0.630000 (  0.631870)
gsub      2.090000   0.000000   2.090000 (  2.094368)
[1..-1]   0.230000   0.010000   0.240000 (  0.232846)
slice     0.320000   0.000000   0.320000 (  0.320714)
length    0.340000   0.000000   0.340000 (  0.341918)
eat!      0.460000   0.000000   0.460000 (  0.452724)
reverse   0.400000   0.000000   0.400000 (  0.399465)
Run Code Online (Sandbox Code Playgroud)

另一个/^./用来找到第一个字符:

require 'benchmark'

N = 1_000_000

class String
  def eat!(how_many = 1)
    self.replace self[how_many..-1]
  end

  def first(how_many = 1)
    self[0...how_many]
  end

  def shift(how_many = 1)
    shifted = first(how_many)
    self.replace self[how_many..-1]
    shifted
  end
  alias_method :shift!, :shift
end

class Array
  def eat!(how_many = 1)
    self.replace self[how_many..-1]
  end
end

puts RUBY_VERSION

STR = "[12,23,987,43"

Benchmark.bm(7) do |b|
  b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
  b.report('[/^./]') { N.times { "[12,23,987,43"[/^./] = '' } }
  b.report('[/^\[/]') { N.times { "[12,23,987,43"[/^\[/] = '' } }
  b.report('sub+') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
  b.report('sub') { N.times { "[12,23,987,43".sub(/^\[/, "") } }
  b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
  b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
  b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
  b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
  b.report('eat!') { N.times { "[12,23,987,43".eat! } }
  b.report('reverse') { N.times { "[12,23,987,43".reverse.chop.reverse } }
end
Run Code Online (Sandbox Code Playgroud)

结果如下:

# >> 2.1.5
# >>               user     system      total        real
# >> [0]       0.270000   0.000000   0.270000 (  0.270165)
# >> [/^./]    0.430000   0.000000   0.430000 (  0.432417)
# >> [/^\[/]   0.460000   0.000000   0.460000 (  0.458221)
# >> sub+      0.590000   0.000000   0.590000 (  0.590284)
# >> sub       0.590000   0.000000   0.590000 (  0.596366)
# >> gsub      1.880000   0.010000   1.890000 (  1.885892)
# >> [1..-1]   0.230000   0.000000   0.230000 (  0.223045)
# >> slice     0.300000   0.000000   0.300000 (  0.299175)
# >> length    0.320000   0.000000   0.320000 (  0.325841)
# >> eat!      0.410000   0.000000   0.410000 (  0.409306)
# >> reverse   0.390000   0.000000   0.390000 (  0.393044)
Run Code Online (Sandbox Code Playgroud)

这是关于更快的硬件和更新版本的Ruby的另一个更新:

2.3.1
              user     system      total        real
[0]       0.200000   0.000000   0.200000 (  0.204307)
[/^./]    0.390000   0.000000   0.390000 (  0.387527)
[/^\[/]   0.360000   0.000000   0.360000 (  0.360400)
sub+      0.490000   0.000000   0.490000 (  0.492083)
sub       0.480000   0.000000   0.480000 (  0.487862)
gsub      1.990000   0.000000   1.990000 (  1.988716)
[1..-1]   0.180000   0.000000   0.180000 (  0.181673)
slice     0.260000   0.000000   0.260000 (  0.266371)
length    0.270000   0.000000   0.270000 (  0.267651)
eat!      0.400000   0.010000   0.410000 (  0.398093)
reverse   0.340000   0.000000   0.340000 (  0.344077)
Run Code Online (Sandbox Code Playgroud)

为什么gsub这么慢?

在进行搜索/替换之后,gsub必须检查可能的其他匹配,然后才能判断它是否已完成.sub只做一个并完成.考虑gsub一下,至少有两个sub电话.

此外,重要的是要记住这一点gsub,并且sub也可能因编写得不好的正则表达式而受到妨碍,这种正则表达式比子字符串搜索要慢得多.如果可能的话,锚定正则表达式以从中获得最大速度.Stack Overflow上有答案,证明如果你想了解更多信息,那就去搜索一下.

  • 值得注意的是,这只适用于Ruby 1.9.在Ruby 1.8中,这将从字符串中删除第一个*byte*,而不是*第一个字符,这不是OP想要的. (33认同)
  • 这将从所有位置删除它,这不是OP想要的:"......对于第一个角色?". (4认同)
  • "那怎么样"[12,23,987,43".shift?`"?那么"[12,23,987,43".shift NoMethodError:未定义的方法`shift'为"[12,23,987,43":String`? (2认同)

bal*_*anv 48

我们可以使用切片来做到这一点:

val = "abc"
 => "abc" 
val.slice!(0)
 => "a" 
val
 => "bc" 
Run Code Online (Sandbox Code Playgroud)

使用slice!我们可以通过指定索引来删除任何字符.

  • 这个优雅的```slice!(0)```真的应该是选择的答案,因为使用```asdf [0] =''``删除第一个字符是荒谬的(就像使用gsub和正则表达式一样)用榴弹炮射击飞行. (2认同)

小智 15

我更喜欢这个

str = "[12,23,987,43"
puts str[1..-1]
>> 12,23,987,43
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望在重复之前检查其他答案.这已由http://stackoverflow.com/a/3614642/128421提出 (2认同)

Chr*_*ald 14

如果您总想剥去前导括号:

"[12,23,987,43".gsub(/^\[/, "")
Run Code Online (Sandbox Code Playgroud)

如果您只想删除第一个字符,并且您知道它不是多字节字符集:

"[12,23,987,43"[1..-1]
Run Code Online (Sandbox Code Playgroud)

要么

"[12,23,987,43".slice(1..-1)
Run Code Online (Sandbox Code Playgroud)


SRa*_*ack 13

从Ruby 2.5开始,您可以使用delete_prefixdelete_prefix!以可读的方式实现此目的.

在这种情况下"[12,23,987,43".delete_prefix("[").

更多信息:

https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/

https://bugs.ruby-lang.org/issues/12694

'invisible'.delete_prefix('in') #=> "visible"
'pink'.delete_prefix('in') #=> "pink"
Run Code Online (Sandbox Code Playgroud)

NB也可以用它来从一个字符串的结尾删除项目delete_suffixdelete_suffix!

'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"
Run Code Online (Sandbox Code Playgroud)

https://bugs.ruby-lang.org/issues/13665

编辑:

使用铁皮人的基准设置,它看起来相当快太(最后两个条目下delete_pdelete_p!).虽然很容易理解,但是对于速度来说并不是很好.

2.5.0
              user     system      total        real
[0]       0.174766   0.000489   0.175255 (  0.180207)
[/^./]    0.318038   0.000510   0.318548 (  0.323679)
[/^\[/]   0.372645   0.001134   0.373779 (  0.379029)
sub+      0.460295   0.001510   0.461805 (  0.467279)
sub       0.498351   0.001534   0.499885 (  0.505729)
gsub      1.669837   0.005141   1.674978 (  1.682853)
[1..-1]   0.199840   0.000976   0.200816 (  0.205889)
slice     0.279661   0.000859   0.280520 (  0.285661)
length    0.268362   0.000310   0.268672 (  0.273829)
eat!      0.341715   0.000524   0.342239 (  0.347097)
reverse   0.335301   0.000588   0.335889 (  0.340965)
delete_p  0.222297   0.000832   0.223129 (  0.228455)
delete_p!  0.225798   0.000747   0.226545 (  0.231745)
Run Code Online (Sandbox Code Playgroud)


小智 6

低效的替代方案:

str.reverse.chop.reverse
Run Code Online (Sandbox Code Playgroud)