我已经想过如何编写Unicode字符串,但仍然对它的工作原理感到困惑.
str <- "ỏ" Encoding(str) # UTF-8 cat(str,file="no-iconv") # Written wrongly as <U+1ECF> cat(iconv(str,to="UTF-8"),file="yes-iconv") # Written correctly as ỏ
我理解为什么no-iconv方法不起作用.这是因为cat(和writeLines也是如此)convert the string into the native encoding first and then to the to=
encoding.在Windows上,这意味着R首先将converts转换为Windows-1252,它无法理解ỏ,从而导致< U 1ECF>.
我不明白为什么yes-iconv方法有效.如果我理解正确,这里的iconv只是返回一个UTF-8编码的字符串.但str已经是UTF-8了!为什么iconv会有什么不同?另外,当iconv(str,to =“UTF-8”)传递给cat时,首先转换到Windows-1252不应该再次搞砸了所有东西吗?
我认为在使用cat()之前将str((副本)str的设置设置为“unknown”不那么神奇并且也可以正常工作.我认为这应该避免cat()中任何不需要的字符集转换.
原文链接:https://www.f2er.com/windows/364398.html这是一个扩展示例,用于演示我认为在原始示例中发生的情况:
print_info <- function(x) { print(x) print(Encoding(x)) str(x) print(charToRaw(x)) } cat("(1) Original string (UTF-8)\n") str <- "\xe1\xbb\x8f" Encoding(str) <- "UTF-8" print_info(str) cat(str,file="no-iconv") cat("\n(2) Conversion to UTF-8,wrong input encoding (latin1)\n") ## from = "" is conversion from current locale,forcing "latin1" here str2 <- iconv(str,from="latin1",to="UTF-8") print_info(str2) cat(str2,file="yes-iconv") cat("\n(3) Converting (2) explicitly to latin1\n") str3 <- iconv(str2,from="UTF-8",to="latin1") print_info(str3) cat(str3,file="latin") cat("\n(4) Setting encoding of (1) to \"unknown\"\n") str4 <- str Encoding(str4) <- "unknown" print_info(str4) cat(str4,file="unknown")
在Windows上的R使用的“Latin-1”语言环境(参见?l10n_info)中,输出文件“yes-iconv”,“latin”和“unknown”应该是正确的(字节序列0xe1,0xbb,0x8f是“ỏ” “).
在“UTF-8”语言环境中,文件“no-iconv”和“unknown”应该是正确的.
示例代码的输出如下,使用在Wine上运行的R 3.3.2 64位Windows版本:
(1) Original string (UTF-8) [1] "ỏ" [1] "UTF-8" chr "<U+1ECF>""| __truncated__ [1] e1 bb 8f (2) Conversion to UTF-8,wrong input encoding (latin1) [1] "á»\u008f" [1] "UTF-8" chr "á»\u008f" [1] c3 a1 c2 bb c2 8f (3) Converting (2) explicitly to latin1 [1] "á»" [1] "latin1" chr "á»" [1] e1 bb 8f (4) Setting encoding of (1) to "unknown" [1] "á»" [1] "unknown" chr "á»" [1] e1 bb 8f
在原始示例中,iconv()使用默认的from =“”参数,这意味着从当前语言环境转换,这实际上是“latin1”.因为str的编码实际上是“UTF-8”,所以字符串的字节表示在步骤(2)中失真,但是当它(可能)将字符串转换回当前语言环境时,由cat()隐式恢复,如通过步骤(3)中的等效转换证明了这一点.