2016-07-07 102 views
6

我已经想通过如何编写Unicode字符串,但仍然困惑于它为什么会起作用。如何在R Windows中将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首先将转换为Windows-1252,这不能理解,导致<U+1ECF>

我不明白的是,为什么yes-iconv方法效果。如果我理解正确,iconv在这里所做的仅仅是返回一个带有UTF-8编码的字符串。但str已经在UTF-8!为什么iconv有什么区别?另外,当iconv(str, to="UTF-8")传递给cat时,不应该再cat把所有东西都弄乱了,首先转换为Windows-1252

+0

我不知道或使用[R自己,而只是阅读文档,'猫()'输出字符串“原样”,和'的iconv()的'mark'参数'默认为true,所以调用'iconv(str,to =“UTF-8”)''将它的输出显式标记为UTF-8,然后传递给'cat()'。也许'str < - “ỏ”'不是以同样的方式标记'str'?您可以使用'enc2utf8(str)'或'Encoding(str)< - “UTF-8”'将'str'明确转换并标记为UTF-8,而不使用'iconv()'。这可能会对'cat()'产生影响。 –

回答

2

我觉得在使用cat()之前将str(的副本)的编码设置为"unknown"并不是那么神奇,而且工作起来也一样。我认为这应该避免在cat()中发生任何不需要的字符集转换。

这里是一个扩展案例来证明什么,我想在原来的例子发生:

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

"Latin-1"区域(见?l10n_info)是在Windows上使用由R,输出文件"yes-iconv""latin""unknown"应是正确的(字节序列0xe1,0xbb,0x8f,它是"ỏ")。

"UTF-8"区域设置中,文件"no-iconv""unknown"应该是正确的。

的示例代码的输出如下所示,,使用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)中失真,但当其(假定)将字符串转换回当前语言环境时,其被隐含地恢复,如步骤(3)中的等效转换。

相关问题