Extrayendo los últimos n caracteres de una cadena ruby


105

Para obtener los últimos ncaracteres de una cadena, asumí que podrías usar

ending = string[-n..-1]

pero si la cadena tiene menos de nletras, obtienes nil.

¿Qué soluciones alternativas están disponibles?

Antecedentes : las cadenas son ASCII sin formato, tengo acceso a ruby ​​1.9.1 y estoy usando Plain Old Ruby Objects (sin marcos web).

Respuestas:


99

Aquí tienes un trazador de líneas, puedes poner un número mayor que el tamaño de la cuerda:

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

Para ruby ​​1.9+

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

Para ruby ​​2.0+, join devuelve una cadena

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

19
Si está usando una versión reciente de Ruby, puede usar en charslugar de dividir.
Andrew Grimm

1
Usé "12345678910" .split (//). Last (7) .join.to_s
Hard-Boiled Wonderland

@ Hard-BoiledWonderland joinfunciona. No creo que necesites el último to_ssi usas unirse.
Andrew Grimm

@AndrewGrimm Tienes razón, para ese caso usé lo anterior con Nokogiri n.xpath('ReferenceID').inner_text.split(//).last(7).join.to_s.to_i. Necesitaba los to_s para realizar el to_i para extraer el valor numérico.
Hard-Boiled Wonderland

Falta .join ; ahora devuelve una matriz de cadenas. En su lugar debería ser "123".split(//).last(5).join(Ruby 2.0.0)
Pavel Nikolov

115

Bueno, la solución más fácil que se me ocurre es:

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

(EDITAR: el oroperador tiene una precedencia menor que la asignación, así que asegúrese de usarlo ||)


+1 ... Creo que esta forma es más fácil de leer que string.reverse[0..n].reverse, lo que me da un segundo de "espera, ¿por qué está haciendo eso?" (o lo haría si no lo estuviera leyendo en el contexto de esta pregunta)
Arkaaito

4
Buena respuesta, pero debería ser en ||lugar de or, o poner paréntesis str[-n..-1] or str.
Andrew Grimm

Buena respuesta, pero no me gusta que ruby ​​no trate s [-inf ..- 1] igual que x [0..inf]
klochner

Gracias por señalar el problema de la precedencia del operador, Andrew. Me atrapa todo el tiempo.
perimosocordiae

@perimosocordiae, no eres el único. stackoverflow.com/questions/372652/…
Andrew Grimm

51

En Ruby recto (sin rieles), puede hacer

string.chars.last(n).join

Por ejemplo:

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 está utilizando Ruby on Rails, puede llamar a métodos firsty lasten un objeto de cadena. Se prefieren estos métodos porque son sucintos e intuitivos.

Por ejemplo:

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

1
Ruby no implica Rails.
Volte

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

Este es el mejor enfoque que veo en esta página que satisface el requisito de poder proporcionar una longitud de carácter final que exceda la longitud total de la cadena.
Rob.Kachmar

1
Por ejemplo, si tiene la intención de tomar los últimos 3 caracteres de un grupo de picaduras como "abcde", "ab" y "a". Esta técnica dará como resultado que "cde", "ab" y "a" utilicen el mismo código para cada uno. "abcde".reverse[0,3].reverse>>> "cde" "ab".reverse[0,3].reverse>>> "ab" "a".reverse[0,3].reverse>>> "a"
Rob.Kachmar

9

Puede utilizar el siguiente código:

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

1
solo código: las respuestas no siempre son útiles. explicar por qué / cómo este código es la solución sería genial
ry8806

6

Para obtener los últimos n caracteres de una cadena, puede hacer esto

a [-n, n] si a es la matriz.

Aquí tienes un ejemplo si quieres uno.

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"


Si el número es demasiado grande, nilse devuelve, que es lo que esta pregunta trataba de evitar específicamente.
Andrew Grimm

Buena respuesta. Limpiar.
Volte

¿Por qué esto está recibiendo votos positivos? Tiene exactamente el mismo problema que lo que el OP estaba preguntando cómo solucionarlo.
jeffdill2

5

¿Has probado una expresión regular?

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

La expresión regular captura tantos caracteres como pueda al final de la cadena, pero no más de n. Y lo guarda en $ 1.


1

Mejora en la respuesta de EmFi.

string[/.{,#{n}}\z/m]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.