web-dev-qa-db-fra.com

Quelle est la différence entre le code hexadécimal (\ x) et les caractères unicode (\ u)?

De ?Quotes:

\xnn   character with given hex code (1 or 2 hex digits)  
\unnnn Unicode character with given code (1--4 hex digits)

Dans le cas où le caractère Unicode n'a qu'un ou deux chiffres, je m'attendrais à ce que ces caractères soient identiques. En fait, l'un des exemples de la page d'aide ?Quotes Montre:

"\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!"

Cependant, sous Linux, lorsque j'essaie d'imprimer un signe dièse, je vois

cat("\ua3")
## £
cat("\xa3")
## �

Autrement dit, le code hexadécimal \x Ne s'affiche pas correctement. (Ce comportement a persisté avec tous les paramètres régionaux que j'ai essayés.) Sous Windows 7, les deux versions affichent un signe dièse.

Si je convertis en entier et vice versa, le signe dièse s'affiche correctement sous Linux.

cat(intToUtf8(utf8ToInt("\xa3")))
## £

Soit dit en passant, cela ne fonctionne pas sous Windows, car utf8ToInt("\xa3") renvoie NA.

Certains caractères \x Renvoient NA sous Windows mais génèrent une erreur sous Linux. Par exemple:

utf8ToInt("\xf0")
## Error in utf8ToInt("\xf0") : invalid UTF-8 string

("\uf0" Est un caractère valide.)

Ces exemples montrent qu'il existe des différences entre les formes de caractères \x Et \u, Qui semblent être spécifiques au système d'exploitation, mais je ne vois aucune logique dans leur définition.

Quelle est la différence entre ces deux formes de caractères?

24
Richie Cotton

La séquence d'échappement \xNN insère l'octet brut NN dans une chaîne, tandis que \uNN insère les octets UTF-8 pour le point de code Unicode NN dans une chaîne UTF-8:

> charToRaw('\xA3')
[1] a3
> charToRaw('\uA3')
[1] c2 a3

Ces deux types de séquence d'échappement ne peuvent pas être mélangés dans la même chaîne:

> '\ua3\xa3'
Error: mixing Unicode and octal/hex escapes in a string is not allowed

En effet, les séquences d'échappement définissent également le encoding de la chaîne. UNE \uNN la séquence définit explicitement le codage de la chaîne entière sur "UTF-8", tandis que \xNN le laisse dans le codage par défaut "inconnu" (aka. native):

> Encoding('\xa3')
[1] "unknown"
> Encoding('\ua3')
[1] "UTF-8"

Cela devient important lors de l'impression de chaînes, car elles doivent être converties en l'encodage de sortie approprié (par exemple, celui de votre console). Les chaînes avec un codage défini peuvent être converties de manière appropriée (voir enc2native), mais ceux avec un codage "inconnu" sont simplement sortis tels quels:

  • Sous Linux, votre console attend probablement du texte UTF-8 et comme 0xA3 n'est pas une séquence UTF-8 valide, elle vous donne "�".
  • Sous Windows, votre console attend probablement du texte Windows-1252 et comme 0xA3 est le bon codage pour "£", c'est ce que vous voyez. (Lorsque la chaîne est \uA3, une conversion de UTF-8 vers Windows-1252 a lieu.)

Si l'encodage est défini explicitement, la conversion appropriée aura lieu sous Linux:

> s <- '\xa3'
> Encoding(s) <- 'latin1'
> cat(s)
£
23
一二三