Odpowiedzi:
Jako Ruby 2.5 można wykorzystać delete_suffixalbo delete_suffix!do osiągnięcia tego celu w sposób szybki i czytelny sposób.
Dokumenty dotyczące metod są tutaj .
Jeśli wiesz, co to jest przyrostek, jest to idiomatyczne (i argumentowałbym, nawet bardziej czytelne niż inne odpowiedzi tutaj):
'abc123'.delete_suffix('123') # => "abc"
'abc123'.delete_suffix!('123') # => "abc"
Jest nawet znacznie szybszy (prawie 40% w metodzie huku) niż najlepsza odpowiedź. Oto wynik tego samego testu porównawczego:
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)
Mam nadzieję, że jest to przydatne - zwróć uwagę, że metoda nie akceptuje obecnie wyrażenia regularnego, więc jeśli nie znasz sufiksu, na razie nie jest to wykonalne. Ponieważ jednak zaakceptowana odpowiedź ( aktualizacja: w momencie pisania ) narzuca to samo, pomyślałem, że może to być przydatne dla niektórych osób.
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]Nie[0..-4]
Jeśli znaki, które chcesz usunąć, są zawsze tymi samymi znakami, zastanów się chomp:
'abc123'.chomp('123') # => "abc"
Zalety chomp: brak liczenia, a kod jaśniej komunikuje, co robi.
Bez argumentów chompusuwa końcówkę wiersza DOS lub Unix, jeśli występuje:
"abc\n".chomp # => "abc"
"abc\r\n".chomp # => "abc"
W komentarzach pojawiło się pytanie o szybkość używania w #chompporównaniu z użyciem zakresu. Oto test porównawczy dwóch:
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
Wyniki testu (przy użyciu 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)
Więc chomp jest szybszy niż użycie zakresu, o ~ 22%.
chomp!()aby działać na ciąg w miejscu.
str = str[0...-n]
sugerowałbym chop . Myślę, że wspomniano o tym w jednym z komentarzy, ale bez linków ani wyjaśnień, dlatego uważam, że lepiej:
Usuwa po prostu ostatni znak z łańcucha i nie musisz określać żadnych wartości, aby tak się stało.
Jeśli chcesz usunąć więcej niż jedną postać, chompto najlepszy wybór. Oto, co mają do powiedzenia rubinowi doktorzychop :
Zwraca nowy ciąg z usuniętym ostatnim znakiem. Jeśli ciąg kończy się na \ r \ n, oba znaki są usuwane. Zastosowanie chop do pustego ciągu zwraca pusty ciąg. Ciąg # chomp jest często bezpieczniejszą alternatywą, ponieważ pozostawia ciąg bez zmian, jeśli nie kończy się separatorem rekordów.
Chociaż jest to używane głównie do usuwania separatorów, takich jak \r\nja użyłem go do usunięcia ostatniego znaku z prostego ciągu, na przykład, saby słowo było liczbą pojedynczą.
Usunięcie ostatnich nznaków jest tym samym, co zachowanie pierwszych length - nznaków.
Aktywne wsparcie obejmuje String#firsti String#lastmetody, które zapewniają wygodny sposób na zachowanie lub upuszczenie pierwszych / ostatnich nznaków:
require 'active_support/core_ext/string/access'
"foobarbaz".first(3) # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3) # => "baz"
"foobarbaz".last(-3) # => "barbaz"
jeśli używasz szyn, spróbuj:
"my_string".last(2) # => "ng"
[EDYTOWANE]
Aby uzyskać ciąg BEZ ostatnich 2 znaków:
n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
Uwaga: ostatni ciąg znaków ma wartość n-1. Tak więc, aby usunąć ostatnie 2, używamy n-3.
Zawsze możesz użyć czegoś takiego
"string".sub!(/.{X}$/,'')
Gdzie Xjest liczba znaków do usunięcia.
Lub z przypisaniem / wykorzystaniem wyniku:
myvar = "string"[0..-X]
gdzie Xjest liczba znaków plus jeden do usunięcia.
Sprawdź slice()metodę:
Jeśli nie masz nic przeciwko tworzeniu metod klas i chcesz odciąć postacie, spróbuj tego:
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'
Za pomocą wyrażenia regularnego:
str = 'string'
n = 2 #to remove last n characters
str[/\A.{#{str.size-n}}/] #=> "stri"
x = "my_test"
last_char = x.split('').last
delete_suffixRuby 2.5. Więcej informacji tutaj .