salto - unicode letras
¿Cuál es la diferencia entre el código hexadecimal(/ x) y el unicode(/ u) caracteres? (2)
De ?Quotes
:
Carácter / xnn con el código hexadecimal dado (1 o 2 dígitos hexadecimales)
/ unnnn carácter Unicode con el código dado (1-4 dígitos hexadecimales)
En el caso en que el carácter Unicode tenga solo uno o dos dígitos, esperaría que estos caracteres sean los mismos. De hecho, uno de los ejemplos en la página de ayuda de ?Quotes
muestra:
"/x48/x65/x6c/x6c/x6f/x20/x57/x6f/x72/x6c/x64/x21"
## [1] "Hello World!"
"/u48/u65/u6c/u6c/u6f/u20/u57/u6f/u72/u6c/u64/u21"
## [1] "Hello World!"
Sin embargo, en Linux, cuando intento imprimir un signo de libra, veo
cat("/ua3")
## £
cat("/xa3")
## �
Es decir, el código hexadecimal /x
no se muestra correctamente. (Este comportamiento persistió con cualquier configuración regional que probé). En Windows 7, ambas versiones muestran un signo de libra.
Si cambio a entero y viceversa, el signo de libra se muestra correctamente en Linux.
cat(intToUtf8(utf8ToInt("/xa3")))
## £
Por cierto, esto no funciona en Windows, ya que utf8ToInt("/xa3")
devuelve NA
.
Algunos /x
caracteres devuelven NA
en Windows pero arrojan un error en Linux. Por ejemplo:
utf8ToInt("/xf0")
## Error in utf8ToInt("/xf0") : invalid UTF-8 string
( "/uf0"
es un personaje válido).
Estos ejemplos muestran que existen algunas diferencias entre las formas de caracteres /x
/u
, que parecen ser específicas del sistema operativo, pero no veo ninguna lógica en cómo se definen.
¿Cuál es la diferencia entre estas dos formas de personaje?
La secuencia de escape /xNN
inserta el byte sin /xNN
NN
en una cadena, mientras que /uNN
inserta los bytes UTF-8 para el punto de código Unicode NN
en una cadena UTF-8:
> charToRaw(''/xA3'')
[1] a3
> charToRaw(''/uA3'')
[1] c2 a3
Estos dos tipos de secuencia de escape no se pueden mezclar en la misma cadena:
> ''/ua3/xa3''
Error: mixing Unicode and octal/hex escapes in a string is not allowed
Esto se debe a que las secuencias de escape también definen la codificación de la cadena. Una secuencia /uNN
establece explícitamente la codificación de toda la cadena en "UTF-8", mientras que /xNN
deja en la codificación predeterminada "desconocida" (también conocida como nativa):
> Encoding(''/xa3'')
[1] "unknown"
> Encoding(''/ua3'')
[1] "UTF-8"
Esto se vuelve importante cuando se imprimen cadenas, ya que deben convertirse a la codificación de salida apropiada (por ejemplo, la de su consola). Las cadenas con una codificación definida se pueden convertir de forma apropiada (ver enc2native
), pero las que tienen una codificación "desconocida" simplemente se envían tal como están:
- En Linux, su consola probablemente está esperando texto UTF-8, y como
0xA3
no es una secuencia UTF-8 válida, le da " ". - En Windows, su consola probablemente esté esperando texto de Windows-1252, y como
0xA3
es la codificación correcta para "£", eso es lo que ve. (Cuando la cadena es/uA3
, tiene lugar una conversión de UTF-8 a Windows-1252).
Si la codificación se establece explícitamente, la conversión apropiada tendrá lugar en Linux:
> s <- ''/xa3''
> Encoding(s) <- ''latin1''
> cat(s)
£
Tomado de Python 2.7 Unicode HOW TO docs:
En el código fuente de Python, los literales Unicode se escriben como cadenas con el prefijo ''u'' o ''U'': u''abcdefghijk ''. Los puntos de código específicos se pueden escribir usando la secuencia de escape / u, que es seguida por cuatro dígitos hexadecimales que dan el punto de código. La secuencia de escape / U es similar, pero espera 8 dígitos hexadecimales, no 4.
Los literales Unicode también pueden usar las mismas secuencias de escape que las cadenas de 8 bits, incluyendo / x, pero / x solo toma dos dígitos hexadecimales para que no pueda expresar un punto de código arbitrario. Los escapes oculares pueden llegar hasta U + 01ff, que es octal 777.
En pocas palabras (espero):
/ 0nn: especifica una secuencia de escape octal de dos dígitos Unicode ''punto de código''.
/ xnn: especifica un "punto de código" unicode hexadecimal de dos dígitos.
/ unnnn - especifica un ''punto de código'' unicode hexadecimal de cuatro dígitos.
/ Unnnnnnnn - especifica un ''punto de código'' hexadecimal de ocho bytes.
Se debe usar el número completo de dígitos, rellenado con los primeros 0.
Por ejemplo:
>>> ord(u''/010'')
8
>>> ord(u''/x10'')
16
>>> ord(u''/020'')
16
>>> ord(u''/x20'')
32
>>> ord(u''/u0020'')
32
>>> ord(u''/U00000020'')
32
>>> ord(u''/u1000'')
4096