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

JP *_*shy 252 ruby string

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

Dig*_*oss 311

irb> 'now is the time'[0...-4]
=> "now is the "
Run Code Online (Sandbox Code Playgroud)

  • 对于那些想知道为什么这个具体例子不起作用的人..有3个点而不是2,即`[0 ...- 4]`不是`[0 ..- 4]` (10认同)
  • 请注意,这仅适用于Ruby 1.9.在Ruby 1.8中,这将删除最后的*字节*,而不是最后的*字符*. (9认同)
  • 这确实有效,但我发现'abc123'.chomp('123')的短和非常长的字符串的速度是两倍.(Ruby 2.0.0-p247)任何人都可以证实这一点吗? (4认同)
  • 但如果他使用1.8.x,他可能意味着*"字节"*. (2认同)
  • @Plamarob我认为说chomp快53纳秒比说它快两倍要更有意义。然后,您可以更好地估计使用它的成本与价值,以及在给定情况下是否可能需要优化。 (2认同)

Way*_*rad 266

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

'abc123'.chomp('123')    # => "abc"
Run Code Online (Sandbox Code Playgroud)

优点chomp是:不计数,代码更清楚地传达它正在做的事情.

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

"abc\n".chomp      # => "abc"
"abc\r\n".chomp    # => "abc"
Run Code Online (Sandbox Code Playgroud)

从评论来看,存在使用速度#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
Run Code Online (Sandbox Code Playgroud)

基准测试结果(使用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)
Run Code Online (Sandbox Code Playgroud)

所以chomp比使用范围更快,大约22%.

  • Chop也是一种选择.关于什么被删除,它不那么挑剔. (5认同)
  • @Plamarob,Ruby中的基准测试通常令人惊讶.我经常犯错,以至于我不再想要猜测什么会更快.此外,如果基准测试结果会改善答案,请随时编辑. (3认同)

Nak*_*lon 55

str = str[0...-n]
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这仅适用于Ruby 1.9.在Ruby 1.8中,这将删除最后的*字节*,而不是最后的*字符*. (5认同)
  • 这比选择的答案更好,因为3点(...)更容易记忆,因为-n意味着从字符串的末尾取出n个字符. (5认同)

kak*_*bei 30

我建议chop.我认为它已在其中一条评论中提及,但没有链接或解释,所以这就是为什么我认为它更好:

它只是从字符串中删除最后一个字符,您不必为此指定任何值.

如果您需要删除多个角色,那么这chomp是您最好的选择.这就是ruby docs所说的chop:

返回删除了最后一个字符的新String.如果字符串以\ r \n结尾,则删除两个字符.将chop应用于空字符串会返回一个空字符串.String#chomp通常是一种更安全的替代方法,因为它不会在记录分隔符中结束时保持字符串不变.

虽然这主要用于删除分隔符,例如\r\n我用它来删除简单字符串中的最后一个字符,例如s使单词成为单数.


sub*_*ing 29

name = "my text"
x.times do name.chop! end
Run Code Online (Sandbox Code Playgroud)

在控制台中:

>name = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do name.chop! end
 => 7 
> name
 => "Nabuco" 
Run Code Online (Sandbox Code Playgroud)


cho*_*boy 15

删除最后一个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"
Run Code Online (Sandbox Code Playgroud)

  • @alex:这是Rails的正确答案. (6认同)
  • Rails 6.0 对 `"foobarbaz".first(-3)` 有一个弃用警告:“使用负整数限制调用 String#first 将在 Rails 6.1 中引发 ArgumentError。” (3认同)

SRa*_*ack 15

Ruby 2.5+

As of Ruby 2.5 you can use delete_suffix or delete_suffix! to achieve this in a fast and readable manner.

The docs on the methods are here.

If you know what the suffix is, this is idiomatic (and I'd argue, even more readable than other answers here):

'abc123'.delete_suffix('123')     # => "abc"
'abc123'.delete_suffix!('123')    # => "abc"
Run Code Online (Sandbox Code Playgroud)

It's even significantly faster (almost 40% with the bang method) than the top answer. Here's the result of the same benchmark:

                     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)
Run Code Online (Sandbox Code Playgroud)

I hope this is useful - note the method doesn't currently accept a regex so if you don't know the suffix it's not viable for the time being. However, as the accepted answer (update: at the time of writing) dictates the same, I thought this might be useful to some people.

  • 这是一个很棒且快速的函数,但这不是正确的答案,因为它没有回答“从字符串中删除最后 n 个字符的首选方法是什么?”的问题。 (4认同)
  • @JPSilvashy 我从未如此高兴地失去了一个复选标记。这是一个很好的答案。 (2认同)

Gui*_*hen 7

如果您使用rails,请尝试:

"my_string".last(2) # => "ng"
Run Code Online (Sandbox Code Playgroud)

[EDITED]

要获得没有最后2个字符的字符串:

n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
Run Code Online (Sandbox Code Playgroud)

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

  • 这不会删除最后两个字母。它返回它们。 (2认同)

Cod*_*lan 5

查看slice()方法:

http://ruby-doc.org/core-2.5.0/String.html#method-i-slice

  • 请注意,这仅适用于 Ruby 1.9。在 Ruby 1.8 中,这将删除最后一个*字节*,而不是最后一个*字符*。 (2认同)