Ruby 从字符串中删除第一个字符的最简单方法是什么?
例如:Ruby 从字符串中删除第一个字符的最简单方法是什么?,ruby,string,Ruby,String,例如: [12,23,987,43 删除“[”最快、最有效的方法是什么, 可以使用chop(),但对于第一个字符?简单方法: 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() (注意:更喜欢简单的方法:)如果您总是想剥去前导
[12,23,987,43
删除“[
”最快、最有效的方法是什么,
可以使用chop()
,但对于第一个字符?简单方法:
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()
(注意:更喜欢简单的方法:)如果您总是想剥去前导支架:
"[12,23,987,43".gsub(/^\[/, "")
如果您只想删除第一个字符,并且知道它不在多字节字符集中,请执行以下操作:
"[12,23,987,43"[1..-1]
或
我有点喜欢用这样的方式: asdf = "[12,23,987,43" asdf[0] = '' p asdf # >> "12,23,987,43" 在我的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)
更新以包含一个以上建议答案:
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)
# >> 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)
另一个使用
/^./
查找第一个字符:
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.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)
# >> 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这么慢
在进行搜索/替换之后,<代码> GSUB/COD>必须检查可能的附加匹配,然后才能判断它是否已完成。<代码>子>代码>只完成一个并完成。请考虑<代码> GSUB/CODE> >它至少是两个代码>子<代码>调用。< /P>
另外,重要的是要记住,
gsub
和sub
也可能会受到写得不好的正则表达式的阻碍,这些正则表达式的匹配速度比子字符串搜索慢得多。如果可能的话,锚定正则表达式以从中获得最快的速度。这里有关于堆栈溢出的答案,说明如果需要更多信息,可以四处搜索.与Pablo的上述答案类似,但它是一种遮阳清洁剂:
str = "[12,23,987,43"
str[0] = ""
str[1..-1]
将返回从1到最后一个字符的数组
'Hello World'[1..-1]
=> "ello World"
例如:a=“一二三”
通过这种方式,您可以逐个删除字符串的第一个字符。我们可以使用slice执行此操作:
val = "abc"
=> "abc"
val.slice!(0)
=> "a"
val
=> "bc"
使用
slice!
我们可以通过指定其索引来删除任何字符。感谢@tin-man将基准放在一起
唉,我真的不喜欢这些解决方案中的任何一个。要么它们需要额外的步骤才能得到结果([0]='
,.strip!
),要么它们对正在发生的事情没有很好的语义/清楚([1..-1]
:“嗯,从1到负1年的范围?”),要么它们写出来很慢或很长(.gsub
,.length
)
我们正在尝试的是“移位”(用数组的说法),但返回的是剩余的字符,而不是移位的字符。让我们使用Ruby使字符串能够实现这一点!我们可以使用快速括号操作,但要给它一个好的名称,并使用arg来指定要从前面咬多少:
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
但是,我们还可以利用这个快速但笨拙的括号操作来做更多的事情。为了完整起见,让我们先为String编写一个\shift
和\35; first
(为什么数组应该有这么多乐趣?),用一个arg指定要从开头删除的字符数:
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
好了,现在我们有了一个很好的从字符串前面提取字符的清晰方法,该方法与Array#first
和Array#shift
一致(这真的应该是一个bang方法??)。我们也可以通过#eat!
轻松获得修改后的字符串。嗯,我们是否应该与Array共享新的eat!
ing功能?为什么不呢
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"
puts str[1..-1]
>> 12,23,987,43
低效替代方案:
str.reverse.chop.reverse
使用正则表达式:
str = 'string'
n = 1 #to remove first n characters
str[/.{#{str.size-n}}\z/] #=> "tring"
Ruby 2.5+
从Ruby 2.5开始,您可以使用
delete_prefix
或delete_prefix!
以可读的方式实现这一点
在这种情况下,“[12,23987,43”。删除前缀(“[”)
更多信息请点击此处:
delete\u后缀
和delete\u后缀!
'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"
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)
我发现一个很好的解决方案是
str.delete(str[0])
,因为它的可读性,尽管我无法证明它的性能
列表=[1,2,3,4]
列表.下拉列表(1)
#=>[2,3,4]
List从数组的开始处删除一个或多个元素,不改变数组,并返回数组本身而不是删除的元素。如果您想保留“chop”语义,可以只
“[12,23987,43”。reverse.chop.reverse
这是一个相当大的性能开销,只需删除一个字符为什么不使用[1..-1]而不是[1.自我长度]?Monkey patching示例对于这个问题来说是非常不合适的,它只是不相关且丑陋。需要注意的是,这只适用于Ruby 1.9。在Ruby 1.8中,这将从字符串中删除第一个字节,而不是第一个字符,这不是OP想要的。+1:我总是忘记,对于字符串位置,您不仅可以指定一个single字符,但您也可以插入子字符串。谢谢!“[12,23987,43”。删除“[”
,从所有位置删除它,这不是OP想要的:“…第一个字符?”。“关于“[12,23987,43.shift”
”?关于“[12,23987,43]的shift NoMethodError:用于“[12,23987,43”的未定义方法:String`?需要注意的是,这只适用于Ruby 1.9。在Ruby 1.8中,这将从字符串中删除第一个字节,而不是第一个字符,这不是OP想要的。我将使用“[12,23987,43”。sub(/^\[+/,”)
而不是gsub(/^\[/,”)
。首先让正则表达式引擎找到所有匹配项,然后在一次操作中替换它们,结果是Ruby 1.9.3的速度提高了约2倍。因为我们处理的是字符串,这应该是gsub(/\a\[/,“”)
?这与几个月前提交的只有他的结果相同。+1看一下我的基准测试结果
'invisible'.delete_prefix('in') #=> "visible"
'pink'.delete_prefix('in') #=> "pink"
'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"
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)