Wyodrębnienie ostatnich n znaków z łańcucha ruby


105

Aby uzyskać ostatnie nznaki z ciągu, założyłem, że możesz użyć

ending = string[-n..-1]

ale jeśli ciąg jest krótszy niż nlitery, otrzymasz nil.

Jakie obejścia są dostępne?

Tło : Ciągi są zwykłym ASCII i mam dostęp do Ruby 1.9.1 i używam zwykłych starych obiektów Ruby (bez frameworków internetowych).

Odpowiedzi:


99

Tutaj masz jedną wkładkę, możesz wpisać liczbę większą niż rozmiar sznurka:

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

Dla Ruby 1.9+

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

W przypadku ruby ​​2.0+, join zwraca łańcuch

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

19
Jeśli używasz najnowszej wersji Rubiego, możesz użyć charszamiast split.
Andrew Grimm,

1
Użyłem „12345678910” .split (//). Last (7) .join.to_s
Hard-Boiled Wonderland

@ Hard-BoiledWonderland joindziała. Myślę, że nie potrzebujesz ostatniej, to_sjeśli używasz dołączenia.
Andrew Grimm,

@AndrewGrimm Masz rację, w tym przypadku użyłem powyższego z Nokogiri n.xpath('ReferenceID').inner_text.split(//).last(7).join.to_s.to_i, potrzebowałem to_s, aby wykonać to_i, aby wyodrębnić wartość liczbową.
Hard-Boiled Wonderland

Brakuje .join - teraz zwraca tablicę ciągów. Zamiast tego powinno być "123".split(//).last(5).join(Ruby 2.0.0)
Pavel Nikolov

115

Cóż, najłatwiejsze obejście, jakie przychodzi mi do głowy, to:

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

(EDYCJA: orOperator ma niższy priorytet niż przypisanie, więc pamiętaj, aby go użyć ||).


+1 ... Myślę, że ten sposób jest łatwiejszy do odczytania niż string.reverse[0..n].reverse, co daje mi sekundę "czekaj, dlaczego on to robi?" (lub zrobiłbym to, gdybym nie czytał tego w kontekście tego pytania)
Arkaaito,

4
Dobra odpowiedź, ale ||zamiast niej orlub umieszczaj ją w nawiasach str[-n..-1] or str.
Andrew Grimm

Dobra odpowiedź, ale nie podoba mi się, że ruby ​​nie traktuje s [-inf ..- 1] tak samo jak x [0..inf]
klochner

Dzięki za zwrócenie uwagi na problem pierwszeństwa operatorów, Andrew. Dostaje mnie za każdym razem.
perimosocordiae

@perimosocordiae nie jesteś jedyny. stackoverflow.com/questions/372652/…
Andrew Grimm

51

W prostym Ruby (bez Railsów) możesz to zrobić

string.chars.last(n).join

Na przykład:

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"

Jeśli używasz Ruby on Rails, możesz wywoływać metody firsti lastobiekt typu string. Te metody są preferowane, ponieważ są zwięzłe i intuicyjne.

Na przykład:

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

1
Ruby nie oznacza Railsów.
Volte

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

Jest to najlepsze podejście, jakie widzę na tej stronie, które spełnia wymóg możliwości podania końcowej długości znaku, która przekracza całkowitą długość ciągu.
Rob.Kachmar

1
Na przykład, jeśli zamierzasz przyjąć ostatnie 3 znaki z grupy żądeł, takich jak „abcde”, „ab” i „a”. Ta technika spowoduje, że „cde”, „ab” i „a” będą używać tego samego kodu dla każdego z nich. "abcde".reverse[0,3].reverse>>> "cde" "ab".reverse[0,3].reverse>>> "ab" "a".reverse[0,3].reverse>>> "a"
Rob.Kachmar

9

Możesz użyć następującego kodu:

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

1
tylko kod - odpowiedzi nie zawsze są pomocne. wyjaśnienie, dlaczego / w jaki sposób ten kod jest poprawką, byłoby świetne
ry8806

6

Aby uzyskać ostatnie n znaków z łańcucha, możesz to zrobić

a [-n, n], jeśli a jest tablicą.

Oto przykład, jeśli chcesz.

ruby-1.9.2-p180: 006> a = "911234567890"

=> „911234567890”

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

=> „67890”

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

=> „4567890”


Jeśli liczba jest zbyt duża, nilzwracana jest wartość, której właśnie próbowano uniknąć w tym pytaniu.
Andrew Grimm,

Dobra odpowiedź. Czysty.
Volte

Dlaczego tak się dzieje? Ma dokładnie ten sam problem, o który pytał OP, jak naprawić.
jeffdill2

5

Czy próbowałeś użyć wyrażenia regularnego?

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

Wyrażenie regularne przechwytuje tyle znaków, ile może na końcu ciągu, ale nie więcej niż n. I przechowuje to za 1 dolara.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.