Извлечение последних 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
Gareve
источник
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]
Rurkss
источник
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 $.

EmFi
источник
1

Улучшение ответа EmFi.

string[/.{,#{n}}\z/m]
сава
источник