2016-07-07 76 views
6

Unicode dizelerinin nasıl yazılacağını anladım, ancak yine de neden işe yaradığını anladım. no-iconv yaklaşım neden çalışmıyorR Windows'da metin dosyasına Unicode dizesi nasıl yazılır?

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 ỏ 

anlıyorum. Çünkü cat (ve writeLines) convert the string into the native encoding first and then to the to= encoding. Pencerelerde, bu demektir ki R'u 'a dönüştürür, bu da 'u anlayamaz ve sonuçta <U+1ECF> olur.

Neyi anlamadığım, neden yes-iconv yaklaşımının çalıştığıdır. Doğru şekilde anlarsam, iconv burada ne yapar UTF-8 kodlamasıyla bir dize döndürmek yeterlidir. Ancak str zaten UTF-8'da! Neden iconv neden bir fark yaratıyor? Ayrıca, iconv(str, to="UTF-8"), cat'a iletildiğinde, cat ilk kez Windows-1252'a dönüştürerek herşeyi bir kez daha karıştırmamalı mıdır?

+0

R kendimi bilmiyorum veya kullanmıyorum, ama sadece belgeleri okuyarak, 'cat()' karakter dizgilerini "olduğu gibi", "iconv()' 'işareti" parametresi ise varsayılan olarak doğrudur. 'iconv (str, to =" UTF-8 ") 'i çağırmak, çıktısını" cat() 'ye iletilmeden önce açıkça UTF-8 olarak işaretler. Belki str <- "ỏ" 'str'yi aynı şekilde işaretlemiyordur? 'Iconv()' işlevini kullanmadan 'str'yi UTF-8 olarak dönüştürmek ve işaretlemek için' enc2utf8 (str) 'veya' Kodlama (str) <- "UTF-8" 'i kullanabilirsiniz. Bu muhtemelen cat() 'için bir fark yaratıyor. –

cevap

2

str'un (bir kopyasını) "unknown"'akullanmadan önce kodlaması daha az sihirdir ve aynı şekilde çalışır. Bu, cat()'da istenmeyen karakter kümesi dönüşümlerinden kaçınmalıdır. İşte

Ben orijinal örnek olur ne düşündüğünü göstermek için genişletilmiş bir örnektir: Windows üzerinde R tarafından kullanıldığı gibi bir "Latin-1" yerelinde

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

(?l10n_info bakınız) çıktı dosyalarını "yes-iconv", "latin" ve "unknown" gerektiği doğru olun (bayt dizisi 0xe1, 0xbb, 0x8f, "ỏ").

"UTF-8" yerel ayarlarında, "no-iconv" ve "unknown" dosyalarının doğru olması gerekir.

Şarap üzerinde çalışan Ar 3.3.2 64-bit Windows sürümünü kullanarak, aşağıdaki gibi örnek kod çıktısı: Orijinal örnekte

(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() dönüşümü anlamına varsayılan from = "" argüman kullanır etkin "latin1" olan mevcut yerel ayar. str kodlaması aslında "UTF-8" olduğu için, dizenin bayt gösterimi adım (2) 'de distorsiyonludur, ancak daha sonra cat() tarafından örtük olarak geri yüklendiğinde (muhtemelen) dizgiyi geçerli yerel konumuna döndürdüğü zaman adımda (3) eşdeğer dönüşüm.