Відповіді:
З Ruby 2.5 ви можете використовувати delete_suffix
або delete_suffix!
домогтися цього швидко та легко читати.
Документи про методи тут .
Якщо ви знаєте, що таке суфікс, це ідіоматично (і я б заперечував, навіть читабельніше, ніж інші відповіді тут):
'abc123'.delete_suffix('123') # => "abc"
'abc123'.delete_suffix!('123') # => "abc"
Це навіть значно швидше (майже 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)
Я сподіваюся, що це корисно - зверніть увагу, що метод наразі не приймає регулярний вираз, тому якщо ви не знаєте суфікс, він наразі нежиттєздатний. Однак, оскільки прийнята відповідь ( оновлення: на момент написання ) диктує те саме, я вважав, що це може бути корисним для деяких людей.
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]
ні[0..-4]
Якщо символи, які ви хочете видалити, завжди є однаковими символами, то врахуйте 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%.
chomp!()
щоб діяти на String на місці.
str = str[0...-n]
Я б запропонував chop
. Я думаю, що це було зазначено в одному з коментарів, але без посилань чи пояснень, тому ось чому я вважаю, що це краще:
Він просто видаляє останній символ із рядка, і вам не потрібно вказувати жодних значень, щоб це відбулося.
Якщо вам потрібно видалити більше одного символу, то chomp
це найкраща ставка. Про це мають сказати рубінові документиchop
:
Повертає нову рядок із останнім видаленим символом. Якщо рядок закінчується \ r \ n, обидва символи видаляються. Застосування chop до порожнього рядка повертає порожній рядок. Рядок # chomp часто є більш безпечною альтернативою, оскільки він залишає рядок незмінним, якщо він не закінчується роздільником записів.
Хоча це використовується в основному для видалення сепараторів типу \r\n
я використовував його для видалення останнього символу з простого рядка, наприклад, s
щоб зробити слово єдиним.
Видалення останніх n
символів - це те саме, що збереження перших length - n
символів.
Активна підтримка включає в себе 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"
якщо ви використовуєте рейки, спробуйте:
"my_string".last(2) # => "ng"
[ЗДОРОВО]
Щоб отримати рядок БЕЗ останніх 2 символів:
n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
Примітка: останній рядковий рядок знаходиться на n-1. Отже, для видалення останніх 2 використовуємо n-3.
Ви завжди можете використовувати щось подібне
"string".sub!(/.{X}$/,'')
Де X
кількість символів для видалення.
Або з призначенням / використанням результату:
myvar = "string"[0..-X]
де X
кількість символів плюс один для видалення.
Перевірте slice()
метод:
Якщо ви все в порядку зі створенням методів класу і хочете, щоб символи, які ви відсікаєте, спробуйте:
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'
Використання регулярного вираження:
str = 'string'
n = 2 #to remove last n characters
str[/\A.{#{str.size-n}}/] #=> "stri"
delete_suffix
з Ruby 2.5. Більше інформації тут .