14

我正在从旧的专有数据库中读取数据。不幸的是,我最终(仅针对某些字符串)Encoding(mychar_vector)返回了"unknown". 不幸的是,我正在使用封闭源代码c hli(宿主语言接口)的包装器,所以我可能对此无能为力——如果是这样,我很高兴在这里被证明是错误的......

但是,查看字符串向量,除了我必须使用字符串进行的一些替换(请参阅我的相关问题)gsub看起来不错。我很想重新获得对编码的控制。有没有办法强制将编码设置为 UTF-8?我尝试过了

Encoding(mychar_vector) <- "UTF-8"
# or
mychar_vector <- enc2utf8(mychar_vector)

但这一切都没有奏效。检查后立即"unknown"退货。也调查了iconv,但显然没有办法从“未知”转换为 UTF-8,因为没有映射。

有没有办法告诉 R,只涉及 UTF-8 字符,因此可以将编码设置为 UTF-8。请注意,向量的某些元素已经是 UTF-8。

4

2 回答 2

3

我也陷入了编码兔子洞,我学到的重要一件事是"unknown"编码并不一定意味着它不是 UTF-8。还是不好。或者需要修复的东西。

这里有些例子:

# Some string that might be UTF-8 or just some ASCII (but created in UTF-8 editor/environment)
ambiguous <- "wat"
Encoding(ambiguous)
#> [1] "unknown"

# Forced coercion to UTF-8 via stringi
ambiguous <- stringi::stri_enc_toutf8("wat", is_unknown_8bit = TRUE)

# Still ambiguous
Encoding(ambiguous)
#> [1] "unknown"

# Some pretty-sure-not-ASCII string
totallygermanic <- "wät"

# It's UTF-8 because that's what my RStudio and every other part of my env is set to
Encoding(totallygermanic)
#> [1] "UTF-8"

# Let's force it to be unknowm
Encoding(totallygermanic) <- "unknown"

# Still prints ok
totallygermanic
#> [1] "wät"

# What's its encoding now?
Encoding(totallygermanic)
#> [1] "unknown"

# Converting it to UTF-8 still prints ok
stringi::stri_enc_toutf8(totallygermanic)
#> [1] "wät"

# So the converted string is UTF-8, right? No.
Encoding(stringi::stri_enc_toutf8(totallygermanic))
#> [1] "unknown"

# Maybe we should just guess?
stringi::stri_enc_detect("wat")
#> [[1]]
#>     Encoding Language Confidence
#> 1 ISO-8859-1       en       0.75
#> 2 ISO-8859-2       ro       0.75
#> 3      UTF-8                0.15

stringi::stri_enc_detect("wät")
#> [[1]]
#>   Encoding Language Confidence
#> 1    UTF-8                 0.8
#> 2 UTF-16BE                 0.1
#> 3 UTF-16LE                 0.1
#> 4  GB18030       zh        0.1
#> 5   EUC-JP       ja        0.1
#> 6   EUC-KR       ko        0.1
#> 7     Big5       zh        0.1

reprex 包(v0.2.1)于 2019 年 2 月 11 日创建

要点是:如果你的字符串不是明显的非 ASCII,例如它只包含字母 az,它可能是 ASCII,或者它可能是 UTF-8,所以你得到一个unknown,但这并不一定意味着你的字符串显然,它实际上不是 UTF-8。您可能会尝试强行强制字符串,在此过程中您可能会破坏一些根本没有破坏的东西。根据我的经验,在变量/向量上使用一些转换函数可能是完全足够stringi::stri_enc_toutf8的,测试它是否按预期打印/工作,也许对可能有问题的字符使用正则表达式过滤器(作为德国人,我们倾向于寻找äöüß)。

无论如何,如果您想深入了解细节,我可以建议您查看stringi软件包及其编码功能。这个包是背后的力量stringr,它提供了一个更高级的接口。

于 2019-02-11T20:38:35.283 回答
1

当我处理了未正确 UTF-8 编码的文件时,我使用 iconv 非常成功地通过在我的 rmarkdown 笔记本中运行 bash 脚本来强制转换文件:

iconv -c -t UTF-8 myfile.txt > Ratebeer-myfile.txt

您也可以试试这个,其中 file 是您的原始文件,而 file-iconv 是修改后的文件:

#iconv −f iso−8859−1 −t UTF−8 file.txt > file-iconv.txt

验证编码:

file -I file-iconv.txt

让我知道这是否有帮助。

于 2017-05-29T19:28:41.867 回答