十六进制代码 (\x) 和 unicode (\u) 字符有什么区别?
What's the difference between hex code (\x) and unicode (\u) chars?
来自?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")
returns NA
.
\x
个字符 return NA
在 Windows 下,但在 Linux 下抛出错误。例如:
utf8ToInt("\xf0")
## Error in utf8ToInt("\xf0") : invalid UTF-8 string
("\uf0"
是一个有效字符。)
这些例子表明 \x
和 \u
字符形式之间存在一些差异,这似乎是 OS-specific,但我看不出任何逻辑它们是如何定义的。
这两种字符形式有什么区别?
转义序列 \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"(又名本机)编码:
> Encoding('\xa3')
[1] "unknown"
> Encoding('\ua3')
[1] "UTF-8"
这在打印字符串时变得很重要,因为它们需要转换为适当的输出编码(例如,您的控制台的输出编码)。可以适当地转换具有已定义编码的字符串(参见 enc2native
),但是具有 "unknown" 编码的字符串将按原样输出:
- 在 Linux 上,您的控制台可能需要 UTF-8 文本,并且由于
0xA3
不是有效的 UTF-8 序列,它会为您提供“�”。
- 在 Windows 上,您的控制台可能需要 Windows-1252 文本,因为
0xA3
是“£”的正确编码,这就是您所看到的。 (当字符串为 \uA3
时,会发生从 UTF-8 到 Windows-1252 的转换。)
如果明确设置了编码,将在 Linux:
上进行适当的转换
> s <- '\xa3'
> Encoding(s) <- 'latin1'
> cat(s)
£
来自?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")
returns NA
.
\x
个字符 return NA
在 Windows 下,但在 Linux 下抛出错误。例如:
utf8ToInt("\xf0")
## Error in utf8ToInt("\xf0") : invalid UTF-8 string
("\uf0"
是一个有效字符。)
这些例子表明 \x
和 \u
字符形式之间存在一些差异,这似乎是 OS-specific,但我看不出任何逻辑它们是如何定义的。
这两种字符形式有什么区别?
转义序列 \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"(又名本机)编码:
> Encoding('\xa3')
[1] "unknown"
> Encoding('\ua3')
[1] "UTF-8"
这在打印字符串时变得很重要,因为它们需要转换为适当的输出编码(例如,您的控制台的输出编码)。可以适当地转换具有已定义编码的字符串(参见 enc2native
),但是具有 "unknown" 编码的字符串将按原样输出:
- 在 Linux 上,您的控制台可能需要 UTF-8 文本,并且由于
0xA3
不是有效的 UTF-8 序列,它会为您提供“�”。 - 在 Windows 上,您的控制台可能需要 Windows-1252 文本,因为
0xA3
是“£”的正确编码,这就是您所看到的。 (当字符串为\uA3
时,会发生从 UTF-8 到 Windows-1252 的转换。)
如果明确设置了编码,将在 Linux:
上进行适当的转换> s <- '\xa3'
> Encoding(s) <- 'latin1'
> cat(s)
£