十六进制代码(\ x)和unicode(\ u)字符之间有什么区别?

时间:2015-10-29 13:19:45

标签: r unicode hex

来自?Quotes

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

在Unicode字符只有一个或两个数字的情况下,我希望这些字符是相同的。事实上,?Quotes帮助页面上的一个示例显示:

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

然而,在Linux下,当我尝试打印英镑符号时,我看到了

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

也就是说,\x十六进制代码无法正确显示。 (这种行为持续存在于我尝试的任何区域设置。)在Windows 7下,两个版本都显示一个井号。

如果我转换为整数然后返回,则在Linux下正确显示井号。

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

顺便说一句,这在Windows下无效,因为utf8ToInt("\xa3")会返回NA

某些\x字符在Windows下返回NA但在Linux下引发错误。例如:

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

"\uf0"是有效字符。)

这些示例表明,\x\u形式的字符之间存在一些差异,这些差异似乎是特定于操作系统的,但我看不出它们如何定义的任何逻辑。

这两种字符形式有什么区别?

1 个答案:

答案 0 :(得分:22)

转义序列\xNN将原始字节NN插入字符串,而\uNN将Unicode代码点NN的UTF-8字节插入UTF- 8字符串:

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

这两种类型的转义序列不能混合在同一个字符串中:

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

这是因为转义序列还定义了字符串的编码\uNN序列将整个字符串的编码显式设置为“UTF-8”,而\xNN将其保留为默认的“unknown”(aka。native)编码:

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

这在打印字符串时变得很重要,因为它们需要转换为适当的输出编码(例如,控制台的编码)。可以适当地转换具有已定义编码的字符串(请参阅enc2native),但具有“未知”编码的字符串只是按原样输出:

  • 在Linux上,您的控制台可能需要UTF-8文本,而0xA3不是有效的UTF-8序列,它会为您提供“ ”。
  • 在Windows上,您的控制台可能需要Windows-1252文本,而0xA3是“£”的正确编码,这就是您所看到的。 (当字符串为\uA3时,会发生从UTF-8到Windows-1252的转换。)

如果明确设置了编码,则在Linux上进行适当的转换:

> s <- '\xa3'
> Encoding(s) <- 'latin1'
> cat(s)
£