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).

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

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.)


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

1
Ruby não implica Rails.
Volte

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

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]

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"


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.


1

Melhoria na resposta da EmFi.

string[/.{,#{n}}\z/m]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.