Руби, удалить последние N символов из строки? - PullRequest
235 голосов
/ 18 ноября 2010

Каков предпочтительный способ удаления последних n символов из строки?

Ответы [ 13 ]

301 голосов
/ 18 ноября 2010
irb> 'now is the time'[0...-4]
=> "now is the "
259 голосов
/ 18 ноября 2010

Если символы, которые вы хотите удалить, всегда являются одними и теми же символами, тогда рассмотрите 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%.

52 голосов
/ 18 ноября 2010
str = str[0...-n]
29 голосов
/ 14 января 2013
name = "my text"
x.times do name.chop! end

Здесь в консоли:

>name = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do name.chop! end
 => 7 
> name
 => "Nabuco" 
28 голосов
/ 10 декабря 2012

Я бы предложил chop. Я думаю, что это было упомянуто в одном из комментариев, но без ссылок или объяснений, поэтому вот почему я думаю, что это лучше:

Он просто удаляет последний символ из строки, и вам не нужно указывать какие-либо значения, чтобы это произошло.

Если вам нужно удалить более одного персонажа, тогда chomp - ваш лучший выбор. Вот что говорят ruby ​​ о chop:

Возвращает новую строку с последним удаленным символом. Если строка заканчивается \ r \ n, оба символа удаляются. Применение отбивной к пустому строка возвращает пустую строку. Строка # chomp часто безопаснее альтернатива, так как оставляет строку неизменной, если она не заканчивается разделитель записей.

Хотя это используется в основном для удаления разделителей, таких как \r\n Я использовал его для удаления последнего символа из простой строки, например s, чтобы сделать слово единственным.

13 голосов
/ 13 сентября 2016

Удаление последних 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"
7 голосов
/ 09 апреля 2015

если вы используете рельсы, попробуйте:

"my_string".last(2) # => "ng"

[EDITED]

Чтобы получить строку без последних 2 символов:

n = "my_string".size
"my_string"[0..n-3] # => "my_stri"

Примечаниепоследняя строка char находится в n-1.Итак, для удаления последних 2 мы используем n-3.

3 голосов
/ 18 ноября 2010

Вы всегда можете использовать что-то вроде

 "string".sub!(/.{X}$/,'')

Где X - количество символов для удаления.

Или с присвоением / использованием результата:

myvar = "string"[0..-X]

где X - количество символов плюс один для удаления.

3 голосов
/ 18 ноября 2010
2 голосов
/ 28 июня 2019

Рубин 2,5 +

Начиная с 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)

Я надеюсь, что это полезно - обратите внимание, что метод в настоящее время не принимает регулярные выражения, поэтому, если вы не знаете суффикс, он пока не жизнеспособен. Однако, поскольку главный ответ диктует то же самое, я подумал, что это может быть полезно для некоторых людей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...