Extraindo os últimos n caracteres de uma string de rubi

105

Para obter os últimos ncaracteres de uma string, presumi que você poderia usar

ending = string[-n..-1]

mas se a string tiver menos do que nletras, você obterá nil.

Quais soluções alternativas estão disponíveis?

Contexto : as strings são ASCII simples e eu tenho acesso ao ruby ​​1.9.1 e estou usando Plain Old Ruby Objects (sem frameworks web).

Andrew Grimm
fonte

Respostas:

99

Aqui você tem um liner, você pode colocar um número maior que o tamanho da string:

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

Para rubi 1.9+

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

Para ruby ​​2.0+, join retorna uma string

"123".split(//).last(5).join
Gareve
fonte
19
Se estiver usando uma versão recente do Ruby, você pode usar em charsvez de dividir.
Andrew Grimm,
1
Usei "12345678910" .split (//). Last (7) .join.to_s
Hard-Boiled Wonderland
@ Hard-BoiledWonderland joinfunciona. Não acho que você precise do último to_sse usar o join.
Andrew Grimm
@AndrewGrimm Você está certo, para esse caso eu usei o acima com Nokogiri n.xpath('ReferenceID').inner_text.split(//).last(7).join.to_s.to_ieu precisava do to_s para realizar o to_i para extrair o valor numérico.
Hard-Boiled Wonderland
Está faltando .join - agora ele retorna uma matriz de strings. Em vez disso, deveria ser "123".split(//).last(5).join(Ruby 2.0.0)
Pavel Nikolov
115

Bem, a solução alternativa mais fácil que posso pensar é:

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

(EDITAR: O oroperador tem precedência inferior à atribuição, portanto, certifique-se de usar em seu ||lugar.)

perimosocordiae
fonte
+1 ... Eu acho que essa forma é mais fácil de ler do que string.reverse[0..n].reverse, o que me dá um segundo de "espere, por que ele está fazendo isso?" (ou faria se eu não estivesse lendo no contexto desta questão)
Arkaaito
4
Boa resposta, mas deveria ser em ||vez de or, ou colocar entre parênteses str[-n..-1] or str.
Andrew Grimm
Boa resposta, mas não gosto que o rubi não trata s [-inf ..- 1] da mesma forma que x [0..inf]
klochner
Obrigado por observar o problema de precedência do operador, Andrew. Me recebe toda vez.
perimosocordiae
@perimosocordiae você não é o único. stackoverflow.com/questions/372652/…
Andrew Grimm
51

Em Ruby direto (sem Rails), você pode fazer

string.chars.last(n).join

Por exemplo:

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"

Se estiver usando Ruby on Rails, você pode chamar métodos firste lastem um objeto string. Esses métodos são preferidos porque são sucintos e intuitivos.

Por exemplo:

[1] pry(main)> a = 'abcdefg'                                                                                                                
 => "abcdefg"
[2] pry(main)> a.first(3)                                                                                                                   
 => "abc"
[3] pry(main)> a.last(4)                                                                                                                    
 => "defg"
Zack Xu
fonte
1
Ruby não implica Rails.
Volte
14
ending = string.reverse[0...n].reverse
Andrew Grimm
fonte
Esta é a melhor abordagem que vejo nesta página que satisfaz o requisito de ser capaz de fornecer um comprimento de caractere final que exceda o comprimento total da string.
Rob.Kachmar
1
Por exemplo, se você pretende pegar os últimos 3 caracteres de um grupo de picadas como "abcde", "ab" e "a". Essa técnica resultará em "cde", "ab" e "a" usando o mesmo código para cada um. "abcde".reverse[0,3].reverse>>> "cde" "ab".reverse[0,3].reverse>>> "ab" "a".reverse[0,3].reverse>>> "a"
Rob.Kachmar
9

Você pode usar o seguinte código:

string[string.length-n,string.length]
Rurkss
fonte
1
apenas código - as respostas nem sempre são úteis. explicar por que / como esse código é a correção seria ótimo
ry8806
6

Para obter os últimos n caracteres de uma string, você pode fazer isso

a [-n, n] se a for a matriz.

Aqui está um exemplo, se você quiser um.

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

=> "911234567890"

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

=> "67890"

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

=> "4567890"

Sunil
fonte
Se o número for muito grande, nilserá retornado, que é o que esta pergunta estava especificamente tentando evitar.
Andrew Grimm
Boa resposta. Limpar \ limpo.
Volte de
Por que isso está recebendo votos positivos? Ele tem exatamente o mesmo problema que o OP estava perguntando como consertar.
jeffdill2
5

Você tentou um regex?

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

O regex captura quantos caracteres puder no final da string, mas não mais do que n. E armazena em $ 1.

EmFi
fonte
1

Melhoria na resposta da EmFi.

string[/.{,#{n}}\z/m]
sawa
fonte