Extraire les n derniers caractères d'une chaîne ruby

105

Pour obtenir les derniers ncaractères d'une chaîne, j'ai supposé que vous pouviez utiliser

ending = string[-n..-1]

mais si la chaîne est inférieure à des nlettres, vous obtenez nil.

Quelles solutions de contournement sont disponibles?

Contexte : Les chaînes sont en ASCII simple, et j'ai accès à ruby ​​1.9.1, et j'utilise des objets Ruby simples (pas de frameworks Web).

Andrew Grimm
la source

Réponses:

99

Ici, vous avez une seule ligne, vous pouvez mettre un nombre supérieur à la taille de la chaîne:

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

Pour rubis 1.9+

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

Pour ruby ​​2.0+, join renvoie une chaîne

"123".split(//).last(5).join
Gareve
la source
19
Si vous utilisez une version récente de Ruby, vous pouvez utiliser charsau lieu de split.
Andrew Grimm
1
J'ai utilisé "12345678910" .split (//). Last (7) .join.to_s
Hard-Boiled Wonderland
@ Hard-BoiledWonderland joinfonctionne. Je ne pense pas que vous ayez besoin du dernier to_ssi vous utilisez join.
Andrew Grimm
@AndrewGrimm Vous avez raison, pour ce cas, j'ai utilisé ce qui précède avec Nokogiri, n.xpath('ReferenceID').inner_text.split(//).last(7).join.to_s.to_ij'avais besoin du to_s pour effectuer le to_i pour extraire la valeur numérique.
Hard-Boiled Wonderland
Il vous manque .join - il renvoie maintenant un tableau de chaînes. Au lieu de cela, il devrait être "123".split(//).last(5).join(Ruby 2.0.0)
Pavel Nikolov
115

Eh bien, la solution de contournement la plus simple à laquelle je puisse penser est:

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

(EDIT: l' oropérateur a une priorité inférieure à l'affectation, assurez-vous donc de l'utiliser à la ||place.)

perimosocordiae
la source
+1 ... Je pense que cette façon est plus facile à lire que string.reverse[0..n].reverse, ce qui me donne une seconde de "attendez, pourquoi fait-il ça?" (ou le ferait si je ne le lisais pas dans le contexte de cette question)
Arkaaito
4
Bonne réponse, mais cela devrait être à la ||place orou mettre des parenthèses str[-n..-1] or str.
Andrew Grimm
Bonne réponse, mais je n'aime pas que ruby ​​ne traite pas s [-inf ..- 1] de la même manière que x [0..inf]
klochner
Merci d'avoir noté le problème de priorité des opérateurs, Andrew. Obtient-moi à chaque fois.
perimosocordiae
@perimosocordiae, vous n'êtes pas le seul. stackoverflow.com/questions/372652/…
Andrew Grimm
51

En Ruby droit (sans Rails), vous pouvez faire

string.chars.last(n).join

Par exemple:

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"

Si vous utilisez Ruby on Rails, vous pouvez appeler des méthodes firstet lastsur un objet chaîne. Ces méthodes sont préférées car elles sont succinctes et intuitives.

Par exemple:

[1] pry(main)> a = 'abcdefg'                                                                                                                
 => "abcdefg"
[2] pry(main)> a.first(3)                                                                                                                   
 => "abc"
[3] pry(main)> a.last(4)                                                                                                                    
 => "defg"
Zack Xu
la source
1
Ruby n'implique pas de Rails.
Volte le
14
ending = string.reverse[0...n].reverse
Andrew Grimm
la source
C'est la meilleure approche que je vois sur cette page qui satisfait l'exigence de pouvoir fournir une longueur de caractère de fin qui dépasse la longueur totale de la chaîne.
Rob.Kachmar
1
Par exemple, si vous avez l'intention de prendre les 3 derniers caractères d'un groupe de piqûres comme "abcde", "ab" et "a". Cette technique aboutira à "cde", "ab" et "a" en utilisant le même code pour chacun. "abcde".reverse[0,3].reverse>>> "cde" "ab".reverse[0,3].reverse>>> "ab" "a".reverse[0,3].reverse>>> "a"
Rob.Kachmar
9

Vous pouvez utiliser le code suivant:

string[string.length-n,string.length]
rurkss
la source
1
code uniquement - les réponses ne sont pas toujours utiles. expliquer pourquoi / comment ce code est le correctif serait génial
ry8806
6

Pour obtenir les n derniers caractères d'une chaîne, vous pouvez le faire

a [-n, n] si a est le tableau.

Voici un exemple si vous en voulez un.

ruby-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"

Sunil
la source
Si le nombre est trop grand, nilest renvoyé, ce que cette question essayait spécifiquement d'éviter.
Andrew Grimm
Bonne réponse. Nettoyer.
Volte le
Pourquoi est-ce que cela suscite des votes? Il a exactement le même problème que ce que l'OP demandait comment résoudre.
jeffdill2
5

Avez-vous essayé une regex?

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

Le regex capture autant de caractères qu'il peut à la fin de la chaîne, mais pas plus de n. Et le stocke dans 1 $.

EmFi
la source
1

Amélioration de la réponse d'EmFi.

string[/.{,#{n}}\z/m]
Sawa
la source