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

例:

[12,23,987,43 

什么是最快,最有效的方法来删除“ [ ”,也许使用一个chop()但为第一个字符?

我喜欢用这样的东西:

 asdf =“[12,23,987,43”
 asdf [0] ='' 

 p asdf
 #>>“12,23987,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 

在我的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) 

更新以结合一个build议的答案:

 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 

其结果是:

 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) 

而另一个使用/^./来查找第一个字符:

 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 

其结果是:

 # >> 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) 

这里是更快的硬件和更新版本的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) 

为什么gsub这么慢?

在进行search/replace之后, gsub必须检查可能的附加匹配,然后才能确定是否完成。 sub只做一个,完成。 考虑gsub ,至less有两个sub调用。

此外,重要的是要记住, gsubsub也可能被写得不好的正则expression式所阻碍,这些正则expression式比子stringsearch要慢得多。 如果可能的话,锚定正则expression式以获得最快的速度。 这里有堆栈溢出的答案,说明如果你想要更多的信息,search一下。

类似于巴勃罗上面的答案,但是一个阴影清洁剂:

 str[1..-1] 

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

 'Hello World'[1..-1] => "ello World" 

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

 val = "abc" => "abc" val.slice!(0) => "a" val => "bc" 

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

如果你总是想去掉尖括号:

 "[12,23,987,43".gsub(/^\[/, "") 

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

 "[12,23,987,43"[1..-1] 

要么

 "[12,23,987,43".slice(1..-1) 

我更喜欢这个

 srt = [12,23,987,43 p srt[1..-1] >> 12,23,987,43 

无效的select:

 str.reverse.chop.reverse 

例如:a =“一二三”

 1.9.2-p290 > a = "One Two Three" => "One Two Three" 1.9.2-p290 > a = a[1..-1] => "ne Two Three" 1.9.2-p290 > a = a[1..-1] => "e Two Three" 1.9.2-p290 > a = a[1..-1] => " Two Three" 1.9.2-p290 > a = a[1..-1] => "Two Three" 1.9.2-p290 > a = a[1..-1] => "wo Three" 

通过这种方式,您可以逐个删除string的第一个字符。

感谢@ the-tin-man把基准放在一起!

唉,我真的不喜欢任何这些解决scheme。 或者他们需要额外的步骤来获得结果( [0] = '' .strip! ),或者他们对于正在发生的事情( [1..-1] )没有很好的语义/清晰度:“范围从1到负1?Yearg?“),或者写出( .gsub.length )很慢或很长。

我们正在尝试的是一种“转换”(用数组的说法),但是返回剩下的字符,而不是被转移的字符。 让我们使用我们的Ruby来使string成为可能! 我们可以使用快速括号操作,但给它一个好名字,并采取一个arg来指定我们想要从前面去掉多less东西:

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

但是,我们可以用快速而笨重的支架操作做更多的事情。 当我们完成时,为了完整#shift ,让我们为String写一个#shift#first (为什么数组要有所有乐趣?),用一个arg来指定我们想要从头开始删除多less个字符:

 class String 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 

好的,现在我们有一个很好的清除string前面的字符的方法,这个方法与Array#firstArray#shift (这实际上应该是一个爆炸方法??)是一致的。 我们可以很容易地获得修改的string以及#eat! 。 嗯,我们应该分享我们的新eat! arrays的力量? 为什么不!

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

现在我们可以:

 > str = "[12,23,987,43" #=> "[12,23,987,43" > str.eat! #=> "12,23,987,43" > str #=> "12,23,987,43" > str.eat!(3) #=> "23,987,43" > str #=> "23,987,43" > str.first(2) #=> "23" > str #=> "23,987,43" > str.shift!(3) #=> "23," > str #=> "987,43" > arr = [1,2,3,4,5] #=> [1, 2, 3, 4, 5] > arr.eat! #=> [2, 3, 4, 5] > arr #=> [2, 3, 4, 5] 

好多了!

简单的方法:

 str = "[12,23,987,43" removed = str[1..str.length] 

令人敬畏的方式:

 class String def reverse_chop() self[1..self.length] end end "[12,23,987,43".reverse_chop() 

(注:喜欢简单的方法:))

 str = "[12,23,987,43" str[0] = "" 
 class String def bye_felicia() felicia = self.strip[0] #first char, not first space. self.sub(felicia, '') end end 

使用正则expression式:

 str = 'string' n = 1 #to remove first n characters str[/.{#{str.size-n}}\z/] #=> "tring" 

从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" 

注意你也可以用delete_suffixdelete_suffix!来删除一个string结尾的项目delete_suffix!

 'worked'.delete_suffix('ed') #=> "work" 'medical'.delete_suffix('ed') #=> "medical" 

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

编辑:

使用Tin Man的基准设置,它看起来也很快(在最后两个条目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)