2008-11-21 11 views
84

En muchos idiomas hay un par de funciones, chr() y ord(), que se convierten entre números y valores de caracteres. En algunos idiomas, ord() se llama asc().¿Qué es lo opuesto a chr() en Ruby?

Ruby tiene Integer#chr, que funciona muy bien:

>> 65.chr 
A 

Justo lo suficiente. ¿Pero cómo vas por el otro lado?

"A".each_byte do |byte| 
    puts byte 
end 

impresiones:

65 

y eso es bastante cerca de lo que quiero. Pero prefiero evitar un bucle: estoy buscando algo lo suficientemente corto como para ser legible cuando declaro un const.

Respuesta

68

Si String # ord no existía en 1.9, lo hace en 2.0:

"A".ord #=> 65 
+0

También funciona en 2.1 – Kostas

2

¿Qué tal

pone un

13

Probar:?

'A'.unpack('c') 
+1

Ahora que Ruby 1.9 ha cambiado el significado de 'A' [0], este es el método más portátil. – AShelly

3

Además, si usted tiene el caracter en una cadena y desea decodificar sin un bucle:

puts 'Az'[0] 
=> 65 
puts 'Az'[1] 
=> 122 
33

En Rubí hasta e incluyendo la serie 1.8, lo siguiente será tanto producir 65 (para ASCII):

puts ?A 
'A'[0] 

El comportamiento ha cambiado en Ruby 1.9, tanto de lo anterior producirá "A" en su lugar. La forma correcta de hacer esto en Ruby 1.9 es:

'A'[0].ord 

Por desgracia, el método ord no existe en Ruby 1.8.

+0

Es desafortunado que la forma "correcta" en Ruby 1.9 sea tan larga, pero al menos se mostrará más fácil en las búsquedas de "ord". Gracias por su respuesta muy detallada. – RJHunter

+2

'A' [0] .ord words en ruby ​​1.8.7 - y gracias por la respuesta. –

10

me gustaría 1 dylanfm y comentario de AShelly pero añaden la [0]:

'A'.unpack('C')[0]

La llamada de desempaquetado devuelve una matriz que contiene un solo número entero, que no siempre es aceptada en un entero es necesario:

 
$ ruby -e 'printf("0x%02X\n", "A".unpack("C"))' 
-e:1:in `printf': can't convert Array into Integer (TypeError) 
    from -e:1 
$ ruby -e 'printf("0x%02X\n", "A".unpack("C")[0])' 
0x41 
$ 

Estoy tratando de escribir el código que funciona en Ruby 1.8.1, 1.8.7 y 1.9.2.

Editado para pasar C para desempaquetar en mayúsculas, porque desempaquetar ("c") me da -1 donde ord() me da 255 (a pesar de correr en una plataforma donde está firmado el carácter de C).

1

usted puede tener estos:

65.chr.ord 
'a'.ord.chr 
3

encontré con esto mientras que la elaboración de una versión pura de Rubí Stringprep a través de RFC.

Mira que chr falla fuera [0255], en lugar de utilizar 1.9.x - reemplazos portátiles 2.1.x:

[22] pry(main)> "\u0221".ord.chr 
RangeError: 545 out of char range 
from (pry):2:in 'chr' 
[23] pry(main)> x = "\u0221".unpack('U')[0] 
=> 545 
[24] pry(main)> [x].pack('U') 
=> "ȡ" 
[25] pry(main)> 
+0

Gracias, esta parece ser la única respuesta que da 'char' y su inversa en el caso de Unicode correctamente – Munyari

2

Si no le importa tirar de los valores de una matriz, puede utilizar "A".bytes

0

estoy escribiendo código para 1.8.6 y 1.9.3 y no pude conseguir ninguna de estas soluciones para trabajar en entornos tanto :(

sin embargo, me encontré con otra solución: http://smajnr.net/2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html

que no funcionó para mí tampoco, pero me adapté para mi uso:

unless "".respond_to?(:ord) 
 
    class Fixnum 
 
    def ord 
 
     return self 
 
    end 
 
    end 
 
end

Una vez hecho esto, entonces el siguiente trabajo, tanto en entornos

'A'[0].ord

+0

Cuando user18096 escribió su respuesta,' "A" .unpack ("C") [0 ] ', que apuntaba a Ruby 1.8.1, Ruby 1.8.7 y Ruby 1.9.2. ¿Falla en tu entorno? ¿Qué tipo de falla? – RJHunter

+0

Hola RJHunter, estoy tratando de convertir un carácter específico en una cadena a su valor numérico. El siguiente código funciona en 1.9.3 pero no en 1.8.6. 'self.status = tagAccountString [4] .unpack ('C') [0]' En 1.8.6 obtengo 'Método undefined de excepción' unpack 'para 0: Fixnum procesa datos de etiqueta almacenados en el búfer principal - exit' el siguiente código funciona (con mi solución propuesta) en ambos entornos 'self.status = tagAccountString [4] .ord' Cualquier consejo (por ejemplo, una mejor solución) es más que bienvenido – hantscolin

+0

' tagAccountString [4] 'devuelve una cadena en más reciente Rubíes pero solía devolver un Fixnum en Ruby 1.8. Es por eso que vio el error, 'método no definido descomprimir para 0: Fixnum'. Podría usar 'status = tagAccountString [4,1] .unpack ('C') [0]' o incluso 'status, = tagAccountString.unpack ('xxxxC')' si siempre quiere ignorar cuatro caracteres y convertir el siguiente uno. – RJHunter