gpt4 book ai didi

r - 自动转义unicode字符

转载 作者:行者123 更新时间:2023-12-02 08:52:22 25 4
gpt4 key购买 nike

如何显示 unicode 字符串,例如:

x <- "•"

使用其转义等效项?

y <- "\u2022"

identical(x, y)
# [1] TRUE

(我希望能够执行此操作,因为 CRAN 包必须仅包含 ASCII,但有时您希望在错误消息或类似消息中使用 unicode)

最佳答案

在深入研究了一些关于 iconv 的文档后,我认为您可以仅使用 base 包来完成此任务。但需要额外注意字符串的编码。

在采用 UTF-8 编码的系统上:

> stri_escape_unicode("你好世界")
[1] "\\u4f60\\u597d\\u4e16\\u754c"

# use big endian
> iconv(x, "UTF-8", "UTF-16BE", toRaw=T)
[[1]]
[1] 4f 60 59 7d 4e 16 75 4c

> x <- "•"
> iconv(x, "UTF-8", "UTF-16BE", toRaw=T)
[[1]]
[1] 20 22

但是,如果您使用的是 latin1 编码的系统,则可能会出现问题。

> x <- "•"
> y <- "\u2022"
> identical(x, y)
[1] FALSE
> stri_escape_unicode(x)
[1] "\\u0095" # <- oops!

# culprit
> Encoding(x)
[1] "latin1"

# and it causes problem for iconv
> iconv(x, Encoding(x), "Unicode")
Error in iconv(x, Encoding(x), "Unicode") :
unsupported conversion from 'latin1' to 'Unicode' in codepage 1252
> iconv(x, Encoding(x), "UTF-16BE")
Error in iconv(x, Encoding(x), "UTF-16BE") :
embedded nul in string: '\0•'

在转换为 Unicode 之前将字符串转换为 UTF-8 更安全:

> iconv(enc2utf8(enc2native(x)), "UTF-8", "UTF-16BE", toRaw=T)
[[1]]
[1] 20 22

编辑:这可能会导致某些特定系统上已经采用 UTF-8 编码的字符串出现一些问题。也许在转换之前检查编码更安全。

> Encoding("•")
[1] "latin1"
> enc2native("•")
[1] "•"
> enc2native("\u2022")
[1] "•"
# on a Windows with default latin1 encoding
> Encoding("测试")
[1] "UTF-8"
> enc2native("测试")
[1] "<U+6D4B><U+8BD5>" # <- BAD!

对于某些字符或语言,UTF-16 可能还不够。因此,您可能应该使用 UTF-32 因为

The UTF-32 form of a character is a direct representation of its codepoint.

根据上述试验和错误,下面可能是我们可以编写的一个更安全的转义函数:

unicode_escape <- function(x, endian="big") {
if (Encoding(x) != 'UTF-8') {
x <- enc2utf8(enc2native(x))
}
to.enc <- ifelse(endian == 'big', 'UTF-32BE', 'UTF-32LE')

bytes <- strtoi(unlist(iconv(x, "UTF-8", "UTF-32BE", toRaw=T)), base=16)
# there may be some better way to do thibs.
runes <- matrix(bytes, nrow=4)
escaped <- apply(runes, 2, function(rb) {
nonzero.bytes <- rb[rb > 0]
ifelse(length(nonzero.bytes) > 1,
# convert back to hex
paste("\\u", paste(as.hexmode(nonzero.bytes), collapse=""), sep=""),
rawToChar(as.raw(nonzero.bytes))
)
})
paste(escaped, collapse="")
}

测试:

> unicode_escape("•••ERROR!!!•••")
[1] "\\u2022\\u2022\\u2022ERROR!!!\\u2022\\u2022\\u2022"
> unicode_escape("Hello word! 你好世界!")
[1] "Hello word! \\u4f60\\u597d\\u4e16\\u754c!"
> "\u4f60\u597d\u4e16\u754c"
[1] "你好世界"

关于r - 自动转义unicode字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25308913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com