Извлечение последних n символов из рубиновой строки


105

Чтобы получить последние nсимволы из строки, я предположил, что вы можете использовать

ending = string[-n..-1]

но если строка меньше nбукв, вы получите nil.

Какие обходные пути доступны?

Предыстория : строки представляют собой простой ASCII, и у меня есть доступ к Ruby 1.9.1, и я использую обычные старые объекты Ruby (без веб-фреймворков).

Ответы:


99

Здесь у вас есть один лайнер, вы можете поставить число больше размера строки:

"123".split(//).last(5).to_s

Для рубина 1.9+

"123".split(//).last(5).join("").to_s

Для Ruby 2.0+ join возвращает строку

"123".split(//).last(5).join

19
Если вы используете последнюю версию Ruby, вы можете использовать charsвместо split.
Эндрю Гримм

1
Я использовал "12345678910" .split (//). Last (7) .join.to_s
Hard-Boiled Wonderland

@ Hard-BoiledWonderland joinработает. Я не думаю, что вам нужно последнее, to_sесли вы используете соединение.
Эндрю Гримм

@AndrewGrimm Вы правы, в этом случае я использовал описанное выше с Nokogiri. n.xpath('ReferenceID').inner_text.split(//).last(7).join.to_s.to_iМне нужны были to_s для выполнения to_i для извлечения числового значения.
Hard-Boiled Wonderland

Вам не хватает .join - теперь он возвращает массив строк. Вместо этого должно быть "123".split(//).last(5).join(Ruby 2.0.0)
Павел Николов

115

Что ж, самый простой обходной путь, о котором я могу думать, это:

ending = str[-n..-1] || str

(РЕДАКТИРОВАТЬ: orоператор имеет более низкий приоритет, чем присвоение, поэтому обязательно используйте его ||.)


+1 ... Я думаю, что это легче читать, чем string.reverse[0..n].reverse, что дает мне секунду "подожди, почему он это делает?" (или если бы я не читал это в контексте этого вопроса)
Arkaaito

4
Хороший ответ, но он должен быть ||вместо orили заключен в круглые скобки str[-n..-1] or str.
Эндрю Гримм

Хороший ответ, но мне не нравится, что рубин не относится к s [-inf ..- 1] так же, как x [0..inf]
klochner 01

Спасибо за внимание к проблеме приоритета оператора, Эндрю. Достает меня каждый раз.
perimosocordiae

@perimosocordiae, ты не единственный. stackoverflow.com/questions/372652/…
Эндрю Гримм

51

В чистом Ruby (без Rails) вы можете

string.chars.last(n).join

Например:

2.4.1 :009 > a = 'abcdefghij'
 => "abcdefghij"
2.4.1 :010 > a.chars.last(5).join
 => "fghij"
2.4.1 :011 > a.chars.last(100).join
 => "abcdefghij"

Если вы используете Ruby on Rails, вы можете вызывать методы firstи lastстроковый объект. Эти методы предпочтительнее, поскольку они краткие и интуитивно понятные.

Например:

[1] pry(main)> a = 'abcdefg'                                                                                                                
 => "abcdefg"
[2] pry(main)> a.first(3)                                                                                                                   
 => "abc"
[3] pry(main)> a.last(4)                                                                                                                    
 => "defg"

1
Ruby не подразумевает Rails.
Volte

14
ending = string.reverse[0...n].reverse

Это лучший подход, который я вижу на этой странице, который удовлетворяет требованию наличия возможности указать длину конечного символа, превышающую общую длину строки.
Роб Качмар 08

1
Например, если вы намереваетесь взять последние 3 символа из группы символов, таких как «abcde», «ab» и «a». Этот метод приведет к тому, что «cde», «ab» и «a» будут использовать один и тот же код для каждого из них. "abcde".reverse[0,3].reverse>>> "cde" "ab".reverse[0,3].reverse>>> "ab" "a".reverse[0,3].reverse>>> "a"
Роб.Качмар

9

Вы можете использовать следующий код:

string[string.length-n,string.length]

1
только код - ответы не всегда полезны. объяснение, почему / как этот код является исправлением, было бы здорово
ry8806

6

Чтобы получить последние n символов из строки, вы можете сделать это

a [-n, n], если a - массив.

Вот и пример, если он вам нужен.

рубин-1.9.2-p180: 006> a = "911234567890"

=> "911234567890"

ruby-1.9.2-p180: 009> a [-5,5]

=> «67890»

ruby-1.9.2-p180: 010> a [-7,7]

=> "4567890"


Если число слишком велико, nilвозвращается, чего специально пытался избежать этот вопрос.
Эндрю Гримм

Хороший ответ. Чистый.
Volte

Почему так набирают голоса? У него та же проблема, что и OP, которую просил исправить.
jeffdill2

5

Вы пробовали регулярное выражение?

string.match(/(.{0,#{n}}$)/)
ending=$1

Регулярное выражение захватывает столько символов, сколько может в конце строки, но не более n. И хранит его в 1 $.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.