使用 Encoding() 和 tokens() 时损坏的编码 UTF-8

问题描述

我在编码方面遇到了很奇怪的问题。当我运行 txt <- c("привет","пока") Encoding(txt) # I get "unkNown" "unkNown" Encoding(txt) <- "UTF-8" Encoding(txt) # I get "UTF-8" "UTF-8",but strange symbols in vector 时,我的编码被破坏,字符串看起来像“\xe7\xed\xe0\xfe\xf2”。

$MBCS
[1] FALSE

$`UTF-8`
[1] FALSE

$`Latin-1`
[1] FALSE

另外,当我运行 l10n_info() 时,我得到

enc2utf8()

我知道,我可以将 R version 4.0.4 (2021-02-15) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows Server 2012 R2 x64 (build 9600) Matrix products: default locale: [1] LC_COLLATE=Russian_Russia.1251 LC_CTYPE=Russian_Russia.1251 LC_MONETARY=Russian_Russia.1251 LC_NUMERIC=C LC_TIME=Russian_Russia.1251 attached base packages: [1] stats graphics Grdevices utils datasets methods base other attached packages: [1] tsne_0.1-3 stringi_1.5.3 tm_0.7-8 NLP_0.2-1 DataCombine_0.2.21 emo_0.0.0.9000 ggplot2_3.3.3 reshape2_1.4.4 [9] topicmodels_0.2-12 ldatuning_1.0.2 writexl_1.3.1 plyr_1.8.6 quanteda_2.9.9000 stringr_1.4.0 readxl_1.3.1 与字符串一起使用,但我使用 quanteda 并遇到与此处相同的问题:https://github.com/quanteda/quanteda/issues/1387(但从 github 重新安装包没有帮助)。我认为,这个问题与服务器上的编码有关。

附言从 excel 加载的数据框显示正确 + 当我将令牌对象保存到新的 xslx 中时,所有字符串都以西里尔文显示

这是我的会话信息:

{{1}}

先谢谢你!

解决方法

编码问题很棘手,尤其是在 Windows 系统上。看起来您的本机编码系统是 Windows-1251,这是西里尔文的 8 位编码。因此,当您输入字符串时,它以该编码输入。您可以将其转换为 Unicode,但如果您使用打印方法,它仍然不一定能正确显示。

这是我尝试在我的 macOS 平台上模拟问题的结果。

> stringi::stri_info()$Charset.native[1:2]
$Name.friendly
[1] "UTF-8"

$Name.ICU
[1] "UTF-8"

我猜你的系统会显示不同的东西,但我不能确定。\

> # on macOS 10.15.7
> txt <- c("привет","пока")
> txt
[1] "\u043f\u0440\u0438\u0432\u0435\u0442" "\u043f\u043e\u043a\u0430"            
> Encoding(txt)
[1] "UTF-8" "UTF-8"

这样会产生与您看到的相同的输出,但它被编码为 UTF-8。为了模拟如果系统将其编码为 Windows-1251 会是什么样子,我们可以对其进行转换:

> # convert to Windows-1251
> txt_1251 <- iconv(txt,from = "UTF-8",to = "WINDOWS-1251")
> print(txt_1251)
[1] "\xef\xf0\xe8\xe2\xe5\xf2" "\xef\xee\xea\xe0"        
> cat(txt_1251)
������ ����> Encoding(txt_1251)
[1] "unknown" "unknown"

这是你看到的吗?

您可以尝试以这种方式修复它:

> txt_from1251 <- stringi::stri_conv(txt_1251,from = "windows-1251",to = "utf-8")
> print(txt_from1251)
[1] "\u043f\u0440\u0438\u0432\u0435\u0442" "\u043f\u043e\u043a\u0430"            
> cat(txt_from1251)
привет пока> Encoding(txt_from1251)
[1] "UTF-8" "UTF-8"

因此,虽然它仍然不打印(),但它从 cat() 正确显示,并且设置了正确的编码位。

我可能错了,因为我对 R 中的 Unicode 和字符集的理解不完整,而且它似乎与平台和语言环境相关。我很高兴看到另一个改进此答案的回复,或者听到您尝试上述建议的一些修复是否成功。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...