Respostas:
A partir do Ruby 2.5, você pode usar delete_suffix
ou delete_suffix!
conseguir isso de maneira rápida e legível.
Os documentos sobre os métodos estão aqui .
Se você sabe qual é o sufixo, isso é idiomático (e eu diria, ainda mais legível do que outras respostas aqui):
'abc123'.delete_suffix('123') # => "abc"
'abc123'.delete_suffix!('123') # => "abc"
É ainda mais rápido (quase 40% com o método bang) do que a resposta principal. Aqui está o resultado da mesma referência:
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)
Espero que isso seja útil - observe que o método atualmente não aceita uma regex, portanto, se você não souber o sufixo, não será viável no momento. No entanto, como a resposta aceita ( atualização: no momento da redação ) dita o mesmo, achei que isso poderia ser útil para algumas pessoas.
What is the preferred way of removing the last n characters from a string?
irb> 'now is the time'[0...-4]
=> "now is the "
[0...-4]
não[0..-4]
Se os caracteres que você deseja remover são sempre os mesmos, considere chomp
:
'abc123'.chomp('123') # => "abc"
As vantagens de chomp
são: sem contagem, e o código comunica mais claramente o que está fazendo.
Sem argumentos, chomp
remove a finalização da linha DOS ou Unix, se uma estiver presente:
"abc\n".chomp # => "abc"
"abc\r\n".chomp # => "abc"
A partir dos comentários, houve uma questão de velocidade de uso #chomp
versus uso de um intervalo. Aqui está uma referência comparando os dois:
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
Resultados de benchmark (usando o 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)
Portanto, o chomp é mais rápido do que usar um intervalo, em ~ 22%.
chomp!()
para atuar no String no local.
str = str[0...-n]
Eu sugeriria chop
. Eu acho que foi mencionado em um dos comentários, mas sem links ou explicações, então aqui está o porquê de eu achar melhor:
Ele simplesmente remove o último caractere de uma string e você não precisa especificar nenhum valor para que isso aconteça.
Se você precisar remover mais de um personagem, então chomp
é sua melhor aposta. Isto é o que os documentos ruby têm a dizer sobre chop
:
Retorna uma nova String com o último caractere removido. Se a sequência terminar com \ r \ n, os dois caracteres serão removidos. A aplicação de chop em uma string vazia retorna uma string vazia. String # chomp é geralmente uma alternativa mais segura, pois mantém a string inalterada se não terminar em um separador de registros.
Embora isso seja usado principalmente para remover separadores, como \r\n
eu usei para remover o último caractere de uma sequência simples, por exemplo, s
para tornar a palavra singular.
Soltando o último n
caracteres é o mesmo que manter os primeiros length - n
caracteres.
O Suporte ativo inclui String#first
e String#last
métodos que fornecem uma maneira conveniente de manter ou eliminar o primeiro / último n
caracteres:
require 'active_support/core_ext/string/access'
"foobarbaz".first(3) # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3) # => "baz"
"foobarbaz".last(-3) # => "barbaz"
se você estiver usando trilhos, tente:
"my_string".last(2) # => "ng"
[EDITADO]
Para obter a string SEM os últimos 2 caracteres:
n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
Nota: a última string char é n-1. Portanto, para remover os dois últimos, usamos o n-3.
Você sempre pode usar algo como
"string".sub!(/.{X}$/,'')
Onde X
está o número de caracteres a serem removidos.
Ou com a atribuição / uso do resultado:
myvar = "string"[0..-X]
onde X
é o número de caracteres mais um para remover.
Confira o slice()
método:
Se você concorda com a criação de métodos de classe e deseja os caracteres cortados, tente o seguinte:
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'
Usando regex:
str = 'string'
n = 2 #to remove last n characters
str[/\A.{#{str.size-n}}/] #=> "stri"
x = "my_test"
last_char = x.split('').last
delete_suffix
Ruby 2.5. Mais informações aqui .