Ответы:
Как рубин 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)
Таким образом, chomp быстрее чем использование диапазона, на ~ 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"
Примечание: последняя строка char имеет значение 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"
x = "my_test"
last_char = x.split('').last
delete_suffix
Ruby 2.5. Больше информации здесь .