stri_unescape_unicode() 在某些字符上失败

stri_unescape_unicode() fails on some characters

我在 R 中转换 unicode 字符时遇到问题。我正在遵循 this 方法,但是库 stringi 中的 stri_unescape_unicode 无法 return 正确的值个案。让我举一个例子,其中正确的值应该是单词 Tomáš:

library(stringi)
test <- "Tom<U+00E1><U+009A>"
test <- gsub("<U\+(....)>", "\\u\1", test)
stri_unescape_unicode(test)
[1] "Tomá\u009a"

但是,如果 šU+0161 rather than U+009A 表示,则一切正常:

test2 <- "Tom<U+00E1><U+0161>"
test2 <- gsub("<U\+(....)>", "\\u\1", test2)
stri_unescape_unicode(test2)
[1] "Tomáš"

现在,我的问题是我有一个很大的 character 向量,其中包含许多元素,例如 teststri_unescape_unicode 在某些字符上失败,例如 <U+009A> 。我的问题是:

看来 stri_unescape_unicode() 没有失败。该字符已被转换,但它是一个控制字符 ("single character introducer" U+009A) 并使用其代码打印。垃圾进,垃圾出。

R 如何打印 Unicode 字符串取决于控制台的类型和使用的语言环境。以下示例已通过 reprex 程序包 运行 使用 Windows 中的代码页 1252。即使不可打印字符是使用 <U+>\u 样式打印的,实际的 Unicode 字符确实存在于相应的 R 字符串中。

library(stringi)
test2 <- c("Tom<U+00E1><U+009A>", "Tom<U+00E1><U+0161>")
test2 <- gsub("<U\+(....)>", "\\u\1", test2)
unesc2 <- stri_unescape_unicode(test2)
unesc2
#> [1] "Tomá<U+009A>" "Tomáš"
nchar(unesc2)
#> [1] 5 5
cap2 <- capture.output(cat(unesc2, sep = "\n"))
cap2
#> [1] "Tomá<U+009A>" "Tomáš"
nchar(cap2)
#> [1] 12  5
which(nchar(cap2) > nchar(unesc2))
#> [1] 1
es2 <- encodeString(unesc2)
es2
#> [1] "Tomá\u009a" "Tomáš"
nchar(es2)
#> [1] 10  5
which(nchar(es2) > nchar(unesc2))
#> [1] 1

我认为 capture.output()encodeString()nchar() 结合使用可以像上面一样检测带有坏字符的字符串,即在当前语言环境中不可打印的字符。然后,如果看起来 U+009A 的所有情况实际上应该是 U+0161,修复这些对于 gsub() 来说是一个简单的工作,例如 gsub("\u009a", "\u0161", unesc2),等等。