从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
调用。
此外,重要的是要记住, gsub
和sub
也可能被写得不好的正则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#first
和Array#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_prefix
或delete_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_suffix
和delete_suffix!
来删除一个string结尾的项目delete_suffix!
'worked'.delete_suffix('ed') #=> "work" 'medical'.delete_suffix('ed') #=> "medical"
https://bugs.ruby-lang.org/issues/13665
编辑:
使用Tin Man的基准设置,它看起来也很快(在最后两个条目delete_p
和delete_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)