R 文本中编码为UTF-8代码的表情符号的翻译和映射

R 文本中编码为UTF-8代码的表情符号的翻译和映射,r,encoding,utf-8,ascii,text-mining,R,Encoding,Utf 8,Ascii,Text Mining,我正在处理包含表情符号的文本。我需要能够找到这些并用可以分析的标签替换它们。如何做到这一点 > main$text[[4]] [1] "Spread d wrd\xf0\u009f\u0098\u008e" > grepl("\xf0", main$text[[4]]) [1] FALSE 我试过上面的方法为什么不起作用?我还尝试将iconv转换成ASCII,然后我得到的字节编码可以用grepl搜索 > abc<-iconv(main$text[[4]], "UTF-8

我正在处理包含表情符号的文本。我需要能够找到这些并用可以分析的标签替换它们。如何做到这一点

> main$text[[4]]
[1] "Spread d wrd\xf0\u009f\u0098\u008e"
> grepl("\xf0", main$text[[4]])
[1] FALSE
我试过上面的方法为什么不起作用?我还尝试将
iconv
转换成ASCII,然后我得到的字节编码可以用grepl搜索

> abc<-iconv(main$text[[4]], "UTF-8", "ASCII", "byte")
> abc
[1] "Spread d wrd<f0><9f><98><8e>"
> grepl("<f0>", abc)
[1] TRUE
我的地图也不一样。用于字节情况的一个很好地工作。但是另一个没有,因为我无法创建搜索所需的
“\ue00e”
。这是另一张地图的示例,对应于软银


搜索多字节UTF-8编码字符的单个字节仅在使用
useBytes=TRUE
时有效。
“\xf0”
这里是多字节字符的一部分,这一事实被Windows上不太完美的Unicode支持R(我想是在原始示例中使用的)所掩盖。如何按字节匹配:

foo <- "\xf0\x9f\x98\x8e" # U+1F60E SMILING FACE WITH SUNGLASSES
Encoding(foo) <- "UTF-8"
grepl("\xf0", foo, useBytes = TRUE)
有效的ASCII码对应于整数0–127。示例中的
iconv()
到ASCII的转换将任何无效字节0xYZ(对应于整数128–255)替换为文本
,其中
y
z
为十六进制数字。据我所知,它不应该引入任何新行(
“\n”

使用问题中链接到的字符列表,下面是一些示例代码,它对输入字符串执行一种“表情符号标记”,即用其(稍微格式化的)名称替换表情符号

在下面的
grep()
调用中,
useBytes
选项的值应该无关紧要。在前面的代码示例中,我使用了
useBytes=TRUE
作为预防措施,因为我不确定Windows上的R处理Unicode代码点
U+10000
和更大的代码点(五位或六位数字)的效果如何。显然,它无法正确打印这些代码点(如
U+1F60E
示例所示),并且无法使用
\U
+8位方法进行输入

问题中的示例显示,R(在Windows上)可以使用
符号而不是
\ue238
打印Unicode字符。原因似乎是
format()
,也用于
print.data.frame()
。例如(适用于在Wine上运行的Windows的R):

>格式(“\ue238”)
[1] ""

在Linux上以8位语言环境进行测试时,默认打印方法已经使用了相同的符号。必须注意的是,在这种情况下,这只是一种打印的表示,与字符最初的存储方式不同。

这就解决了问题。我意识到一些表情符号被编码为他们的软银编码(“”),其余的则被编码为一系列字节,对应于正常的UTF-8编码(“\xf0\u009f\u0098”)。为什么会这样?另一个问题是,我有一张所有软银编码的地图。(“e00e”,“e051”),但要使此内容可搜索,我需要使用
grepl(“\ue00e”,…)
。那么如何将“\”添加到字符串中呢?我用
fixed=T
尝试了
paste
gsub
,但没有效果。如果您有一个文本字符串
abc,但是那里的字符不能通过
grepl(“,…)
进行搜索。我已在问题中加入有关资料。数据集中的编码非常混乱。我阅读了附录并相应地编辑了我的答案。我希望这能消除混乱。
 emmm[11]
[1] "E238"
foo <- "\xf0\x9f\x98\x8e" # U+1F60E SMILING FACE WITH SUNGLASSES
Encoding(foo) <- "UTF-8"
grepl("\xf0", foo, useBytes = TRUE)
grepl(foo, paste0("Smiley: ", foo, " and more"), useBytes = TRUE)
emoji_table <- read.csv2("https://github.com/today-is-a-good-day/Emoticons/raw/master/emDict.csv",
                         stringsAsFactors = FALSE)

emoji_names <- emoji_table[, 1]
text_bytes_to_raw <- function(x) {
    loc <- gregexpr("\\x", x, fixed = TRUE)[[1]] + 2
    as.raw(paste0("0x", substring(x, loc, loc + 1)))
}
emoji_raw <- lapply(emoji_table[, 3], text_bytes_to_raw)
emoji_utf8 <- vapply(emoji_raw, rawToChar, "")
Encoding(emoji_utf8) <- "UTF-8"

gsub_many <- function(x, patterns, replacements) {
    stopifnot(length(patterns) == length(replacements))
    x2 <- x
    for (k in seq_along(patterns)) {
        x2 <- gsub(patterns[k], replacements[k], x2, useBytes = TRUE)
    }
    x2
}

tag_emojis <- function(x, codes, names) {
    gsub_many(x, codes, paste0("<", gsub("[[:space:]]+", "_", names), ">"))
}

each_tagged <- tag_emojis(emoji_utf8, emoji_utf8, emoji_names)

all_in_one <- tag_emojis(paste0(emoji_utf8, collapse = ""),
                         emoji_utf8, emoji_names)

stopifnot(identical(paste0(each_tagged, collapse = ""), all_in_one))
library(stringi)

hex4_to_utf8 <- function(x) {
    stopifnot(grepl("^[[:xdigit:]]{4}$", x))
    stringi::stri_enc_toutf8(stringi::stri_unescape_unicode(paste0("\\u", x)))
}

foo <- "E238"
foo_utf8 <- hex4_to_utf8(foo)
> format("\ue238")
[1] "<U+E238>"