十六进制代码 (\x) 和 unicode (\u) 字符有啥区别?

Posted

技术标签:

【中文标题】十六进制代码 (\\x) 和 unicode (\\u) 字符有啥区别?【英文标题】:What's the difference between hex code (\x) and unicode (\u) chars?十六进制代码 (\x) 和 unicode (\u) 字符有什么区别? 【发布时间】:2016-01-29 15:54:47 【问题描述】:

来自?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 字符形式之间存在一些差异,这似乎是特定于操作系统的,但我看不出它们是如何定义的任何逻辑。

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

【问题讨论】:

那是 C# 但它可能对你有帮助,因为它是同一个问题:***.com/questions/32175482/… @etienne 如果简而言之,Richie 本人会给出详细的 wiki 答案,我不会感到惊讶。 @DavidArenburg:不,他只是在推特上发了这个问题,所以他一定被难住了。 :) @JoshuaUlrich 是的,完全被难住了。我怀疑这两件事是一样的,而且这些怪癖是错误,但我想在 R-core 咆哮之前我会问你们好人。 我认为 charToRaw 会帮助你解决这个问题 【参考方案1】:

转义序列\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 将其保留为默认的“未知”(又名原生)编码:

> 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)
£

【讨论】:

以上是关于十六进制代码 (\x) 和 unicode (\u) 字符有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

__x__(55)0919第八天__字符串中使用 u 输出Unicode字符

JS 中文 UTF-8编码互转

十六进制字符串转UNICODE 和 互转

正则表达式

python 2 与 python 3 —— 转义及编码(u x)

C++ Win32api 从用户输入输出 Unicode