为什么 stringr 在操作字符串时改变编码?
Why is stringr changing encoding when manipulating strings?
stringr
有这种奇怪的行为,真让我恼火。 stringr
在没有警告的情况下改变了一些包含奇异字符的字符串的编码,在我的例子中是 ø、å、æ、é 和其他一些......如果你 str_trim
一个字符向量,那么那些带有外来字母将转换为新的编码。
letter1 <- readline('Gimme an ASCII character!') # try q or a
letter2 <- readline('Gimme an non-ASCII character!') # try ø or é
Letters <- c(letter1, letter2)
Encoding(Letters) # 'unknown'
Encoding(str_trim(Letters)) # mixed 'unknown' and 'UTF-8'
这是一个问题,因为我使用 data.table 来(快速)合并大表,而 data.table 不支持混合编码,而且我找不到返回到统一编码。
有什么变通办法吗?
编辑:我想我可以回到基本功能,但它们也不保护编码。 paste
保留它,但不 sub
例如。
Encoding(paste(' ', Letters)) # 'unknown'
Encoding(str_c(' ', Letters)) # mixed
Encoding(sub('^ +', '', paste(' ', Letters))) # mixed
stringr
正在更改编码,因为 stringr
是 stringi
包的包装器,并且 stringi
始终以 UTF-8 编码。有关此设计选择的详细信息和解释,请参阅 help("stringi-encoding", package = "stringi")
。
为避免合并 data.table
时出现问题,只需确保所有 id
变量均以 UTF-8 编码。您可以使用 stringi
包中的 stri_enc_toutf8
或使用 iconv
.
R 并不总是使编码之间的转换变得容易(有函数 iconv
,但此函数接受的内容取决于平台)。但是,至少您始终可以将字符串的编码标记重置为“未知”:
Letters = str_trim(Letters)
Encoding(Letters)
# [1] "unknown" "UTF-8"
Encoding(Letters) = ''
Encoding(Letters)
# [1] "unknown" "unknown"
但是,请注意,这只是 标记 字符串的编码,实际上并没有重新编码字符串。因此,这会导致数据出现乱码。正如评论中所提到的,这充其量只是一个 hack,而不是问题的实际解决方案。
Encoding
举例说明了 R 无法正确处理编码的问题。文档说:
ASCII strings will never be marked with a declared encoding, since their representation is the same in all supported encodings.
… 这显然根本没有帮助(而且还有点误导;仅由 < 128 的代码点组成的 UTF-8 字符串可能看起来与 ASCII 字符串没有区别,但对其进行操作应该会产生不同的结果,具体取决于关于编码,这就是为什么它应该有效标记的原因)。
有趣的是,enc2native
和 enc2utf8
都不会在这里完成所需的事情 — 两者都会对 Letters
中的两个字符串产生不同的编码,这是 Encoding
上面引用的问题。
有了 this recent commit,data.table 现在通过确保在创建 data.table 时使用正确的编码以及通过确保 [=] 等函数中的正确编码来隐式处理这些混合编码10=] 和 duplicated()
.
查看 README.md 中 v1.9.7 的错误下的新闻项目 (23)。
如果您遇到任何进一步的问题,请测试并回信。
stringr
有这种奇怪的行为,真让我恼火。 stringr
在没有警告的情况下改变了一些包含奇异字符的字符串的编码,在我的例子中是 ø、å、æ、é 和其他一些......如果你 str_trim
一个字符向量,那么那些带有外来字母将转换为新的编码。
letter1 <- readline('Gimme an ASCII character!') # try q or a
letter2 <- readline('Gimme an non-ASCII character!') # try ø or é
Letters <- c(letter1, letter2)
Encoding(Letters) # 'unknown'
Encoding(str_trim(Letters)) # mixed 'unknown' and 'UTF-8'
这是一个问题,因为我使用 data.table 来(快速)合并大表,而 data.table 不支持混合编码,而且我找不到返回到统一编码。
有什么变通办法吗?
编辑:我想我可以回到基本功能,但它们也不保护编码。 paste
保留它,但不 sub
例如。
Encoding(paste(' ', Letters)) # 'unknown'
Encoding(str_c(' ', Letters)) # mixed
Encoding(sub('^ +', '', paste(' ', Letters))) # mixed
stringr
正在更改编码,因为 stringr
是 stringi
包的包装器,并且 stringi
始终以 UTF-8 编码。有关此设计选择的详细信息和解释,请参阅 help("stringi-encoding", package = "stringi")
。
为避免合并 data.table
时出现问题,只需确保所有 id
变量均以 UTF-8 编码。您可以使用 stringi
包中的 stri_enc_toutf8
或使用 iconv
.
R 并不总是使编码之间的转换变得容易(有函数 iconv
,但此函数接受的内容取决于平台)。但是,至少您始终可以将字符串的编码标记重置为“未知”:
Letters = str_trim(Letters)
Encoding(Letters)
# [1] "unknown" "UTF-8"
Encoding(Letters) = ''
Encoding(Letters)
# [1] "unknown" "unknown"
但是,请注意,这只是 标记 字符串的编码,实际上并没有重新编码字符串。因此,这会导致数据出现乱码。正如评论中所提到的,这充其量只是一个 hack,而不是问题的实际解决方案。
Encoding
举例说明了 R 无法正确处理编码的问题。文档说:
ASCII strings will never be marked with a declared encoding, since their representation is the same in all supported encodings.
… 这显然根本没有帮助(而且还有点误导;仅由 < 128 的代码点组成的 UTF-8 字符串可能看起来与 ASCII 字符串没有区别,但对其进行操作应该会产生不同的结果,具体取决于关于编码,这就是为什么它应该有效标记的原因)。
有趣的是,enc2native
和 enc2utf8
都不会在这里完成所需的事情 — 两者都会对 Letters
中的两个字符串产生不同的编码,这是 Encoding
上面引用的问题。
有了 this recent commit,data.table 现在通过确保在创建 data.table 时使用正确的编码以及通过确保 [=] 等函数中的正确编码来隐式处理这些混合编码10=] 和 duplicated()
.
查看 README.md 中 v1.9.7 的错误下的新闻项目 (23)。
如果您遇到任何进一步的问题,请测试并回信。