如何最好地从字符串中移除最后的n
个字符?
irb> 'now is the time'[0...-4]
=> "now is the "
[0...-4]
而不是[0..-4]
。 - rorofromfrance'abc123'.chomp('123') # => "abc"
< p > 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)
使用chomp比使用范围快,速度提高了约22%。
chomp!()
原地对字符串进行操作。 - Joshua Pinter从 Ruby 2.5 开始,您可以使用 delete_suffix
或 delete_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)
我希望这对你有用 - 请注意,该方法当前不接受正则表达式,因此如果你不知道后缀,目前无法使用。然而,由于被接受的答案(更新:撰写时)也是这样规定的,我认为这可能对一些人有用。
str = str[0..-1-n]
与 [0...-n]
不同,这个处理了 n=0 的情况。
str [0 ...-0]
是""
而不是"123"
。 您实际上想要str [0..-(n + 1)]
。 - movermeyer我建议使用 chop
。我认为在其中的一篇评论中提到过,但没有链接或解释,下面是我觉得它更好的原因:
它只是从字符串中删除最后一个字符,您不需要指定任何值就可以完成操作。
如果您需要删除多于一个字符,则最好使用chomp
。这是Ruby文档对chop
的描述:
返回删除了最后一个字符的新字符串。如果字符串以 \r\n 结尾,则两个字符都会被删除。将 chop 应用于空字符串将返回空字符串。通常情况下,String#chomp 是更安全的选择,因为如果字符串不以记录分隔符结尾,则它不会更改该字符串。
虽然这主要用于删除分隔符(例如 \r\n
),但我已经将其用于从简单字符串中删除最后一个字符,例如将s
去掉以使单词变为单数。
name = "my text"
x.times do name.chop! end
在控制台中:
>name = "Nabucodonosor"
=> "Nabucodonosor"
> 7.times do name.chop! end
=> 7
> name
=> "Nabuco"
去掉末尾的 n
个字符与保留前 length - n
个字符是相同的。
Active Support 包括 String#first
和 String#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"
"foobarbaz".first(-3)
上发出了一个过时警告:"在 Rails 6.1 中,使用负整数作为 String#first 的参数将会抛出 ArgumentError 异常。" - Toby 1 Kenobi"my_string".last(2) # => "ng"
n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
看一下slice()
方法:
http://ruby-doc.org/core-2.5.0/String.html#method-i-slice
"string".sub!(/.{X}$/,'')
在这里,X
代表要删除的字符数。
或者使用赋值/使用结果的方法:
myvar = "string"[0..-X]
其中X
是要移除的字符数加一。
delete_suffix
。更多信息请参见此处。 - SRack