Ruby,从字符串中删除最后N个字符?


263

n从字符串中删除最后一个字符的首选方法是什么?


如果您知道后缀(最常见的答案表明有很多可以找到的后缀),则可以delete_suffix在Ruby 2.5中使用。更多信息在这里
SRack

Answers:


36

红宝石2.5+

从Ruby 2.5开始,您可以使用delete_suffixdelete_suffix!以快速且易读的方式实现此目的。

方法的文档在这里

如果您知道后缀是什么,这是惯用的(我认为,比这里的其他答案更具可读性):

'abc123'.delete_suffix('123')     # => "abc"
'abc123'.delete_suffix!('123')    # => "abc"

它甚至比最上面的答案要快得多(使用bang方法几乎快40%)。这是相同基准测试的结果:

                     user     system      total        real
chomp            0.949823   0.001025   0.950848 (  0.951941)
range            1.874237   0.001472   1.875709 (  1.876820)
delete_suffix    0.721699   0.000945   0.722644 (  0.723410)
delete_suffix!   0.650042   0.000714   0.650756 (  0.651332)

我希望这是有用的-请注意,该方法当前不接受正则表达式,因此,如果您不知道后缀,则暂时不可行。但是,正如被接受的答案(更新:在撰写本文时)指出的那样,我认为这对某些人可能有用。


1
@JPSilvashy我从未如此高兴地失去选中标记。这是一个很好的答案。
韦恩·康拉德

1
这是一项强大而快速的功能,但这不是正确的答案,因为它无法回答确切的问题What is the preferred way of removing the last n characters from a string?
山姆

1
感谢@Sam的反馈-这个问题已经有将近9年的答案了,与本文相同,在撰写本文时有261票赞成。JP接受了这一点,最近又转而使用它,因此我想说它回答了他们的问题:)我以为我会将此作为一种现代替代方法出现,并希望它能帮助在这里的人们。实际上,我已经解决了所有这些问题-我希望这种方法能很快接受正则表达式,尽管在此之下您的情况有一个完美的选择。
SRack

316
irb> 'now is the time'[0...-4]
=> "now is the "

9
请注意,这仅在Ruby 1.9中有效。在Ruby 1.8中,这将删除最后一个字节,而不是最后一个字符
约尔格W¯¯米塔格

2
但是,如果他使用的是1.8.x,则可能是“字节”。
DigitalRoss

4
这确实有效,但是我发现'abc123'.chomp('123')对于短字符串和长字符串都快两倍。(Ruby 2.0.0-p247)有人可以确认吗?
Plasmarob

10
对于那些想知道为什么这个特定示例不起作用的人..有3个点而不是2点,即[0...-4]不是[0..-4]
rorofromfrance 2013年

2
@Plamarob我认为说chomp快53纳秒比说它快两倍要更有意义。然后,您可以更好地估计使用它的成本与价值,以及在给定情况下是否可能需要优化。
cesoid 2016年

266

如果要删除的字符始终是相同的字符,请考虑chomp

'abc123'.chomp('123')    # => "abc"

的优点chomp是:无需计数,并且代码可以更清楚地传达其正在执行的操作。

如果没有参数,则chomp删除DOS或Unix行结尾(如果存在):

"abc\n".chomp      # => "abc"
"abc\r\n".chomp    # => "abc"

从评论中可以#chomp看出,使用速度与使用范围的速度有关。这是比较两者的基准:

require 'benchmark'

S = 'asdfghjkl'
SL = S.length
T = 10_000
A = 1_000.times.map { |n| "#{n}#{S}" }

GC.disable

Benchmark.bmbm do |x|
  x.report('chomp') { T.times { A.each { |s| s.chomp(S) } } }
  x.report('range') { T.times { A.each { |s| s[0...-SL] } } }
end

基准测试结果(使用CRuby 2.13p242):

Rehearsal -----------------------------------------
chomp   1.540000   0.040000   1.580000 (  1.587908)
range   1.810000   0.200000   2.010000 (  2.011846)
-------------------------------- total: 3.590000sec

            user     system      total        real
chomp   1.550000   0.070000   1.620000 (  1.610362)
range   1.970000   0.170000   2.140000 (  2.146682)

因此,排骨比使用范围快约22%。


5
印章也是一种选择。对于删除的内容,它并不那么繁琐。
Andrew Grimm

1
我发现事实恰恰相反。现实情况是,.chomp似乎始终是两倍。
Plasmarob

3
@ Plamarob,Ruby中的基准通常令人惊讶。我经常错了,我不再试图猜测会更快。此外,如果基准测试结果可以改善答案,请随时对其进行编辑。
韦恩·康拉德

1
如果我没看错代码,范围比chomp要长约53纳秒。在某些情况下,这可能是一个很大的阻力,但是牢记绝对速度(而不是相对速度)可能会告诉您是否应该遍历代码库并将所有范围更改为chomp(适用时)。可能不是。
cesoid

1
效果很好。您可以使用chomp!()它就地对String进行操作。
约书亚·品特

57
str = str[0...-n]

5
请注意,这仅在Ruby 1.9中有效。在Ruby 1.8中,这将删除最后一个字节,而不是最后一个字符
约尔格W¯¯米塔格

5
这比选择的答案更好,因为3点(...)更容易记忆,因为-n表示从字符串末尾取出n个字符。
lulalala 2011年

也是“ abcd” [0 ..- 2]#=>“ abc”,而“ abcd” [0 ...- 2]#=>“ ab”。在我看来,“ 3点范围”选项会产生更多自我解释的代码。
mokagio

31

我建议chop。我认为它已在评论之一中提到,但没有链接或解释,因此这就是我认为更好的原因:

它只是从字符串中删除最后一个字符,而不必指定任何值来实现。

如果您需要删除多个字符,那么chomp最好的选择是。这是ruby文档必须说的chop

返回删除了最后一个字符的新String。如果字符串以\ r \ n结尾,则两个字符都将被删除。将chop应用于空字符串将返回一个空字符串。String#chomp通常是一种更安全的选择,因为如果字符串未以记录分隔符结尾,则它将保持不变。

尽管此方法主要用于删除分隔符,例如\r\n我已使用它来删除简单字符串中的最后一个字符,例如使用s来使单词为单数。


1
那会不会只是删除最后一个字符?问题是关于“字符”的复数形式
maetthew

1
是的,您是对的,但是chomp('chars')将删除最后一个'chars'。对我来说,尚不清楚OP是否需要特定字符或仅N个字符。
kakubei

是的,只有当您只想删除一个字符时(这就是我的情况),这才是答案。
6

29
name = "my text"
x.times do name.chop! end

在控制台中:

>name = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do name.chop! end
 => 7 
> name
 => "Nabuco" 

这样有效吗?似乎值得将其与其他答案进行基准比较:)
SRack

16

删除最后一个n字符与保留第一个字符相同length - n字符。

Active Support包括String#firstString#last提供了方便的方法来保留或删除第一个/最后一个n字符的方法:

require 'active_support/core_ext/string/access'

"foobarbaz".first(3)  # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3)   # => "baz"
"foobarbaz".last(-3)  # => "barbaz"

7

如果您使用滑轨,请尝试:

"my_string".last(2) # => "ng"

[编辑]

要获取字符串而没有最后两个字符:

n = "my_string".size
"my_string"[0..n-3] # => "my_stri"

注意:最后一个字符串char在n-1处。因此,要删除最后一个2,我们使用n-3。


2
这不会删除最后两个字母。它返回它们。
JP Silvashy 2015年

1
您不需要先测量字符串,ruby会从字符串末尾使用负索引作为本机
Devon Parsons

3

您可以随时使用类似

 "string".sub!(/.{X}$/,'')

X要删除的字符数在哪里。

或分配/使用结果:

myvar = "string"[0..-X]

其中X的字符数加一个要删除的字符。



1

如果您可以创建类方法并且希望将字符砍掉,请尝试以下操作:

class String
  def chop_multiple(amount)
    amount.times.inject([self, '']){ |(s, r)| [s.chop, r.prepend(s[-1])] }
  end
end

hello, world = "hello world".chop_multiple 5
hello #=> 'hello '
world #=> 'world'


0

如果要删除的字符始终是相同的字符,请考虑使用chomp:

'abc123'。排骨('123')


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.