r - twitteR 和 R 的 Twitter 表情符号编码问题

标签 r twitter encoding utf-8 emoji

我正在尝试建立一种在 twitter 中查找表情符号的方法,并将它们与人们可以在 unicode.org 中找到的 unicode 表相关联,但我发现很难识别它们,因为我认为是编码问题或只是我的误解这个话题。简而言之,我所做的是从 http://www.unicode.org/emoji/charts/full-emoji-list.html 中找到的表中构建一个表情符号“库”。包含表情符号的标题和代码点(代码)。我用库 rvest 在 R 中废弃了它。

当我使用 R 中的 twitteR API 从 twitter 获取信息时,问题就出现了。因为表情符号的代码看起来根本不像这个表中的代码。

让我们以 100(一百点)红色图标的表情符号为例。这是前链表中的数字1468,其码位代码为:

U+1F4AF

现在,当我从 twitter 获取它时,首先它在 API 内置的用于处理推文的状态类中显示为这样。
\xed��\xed��

然后,一旦我将其转换为数据帧,我也会使用来自 twitter API 的内置函数来执行此操作。例如:
tweet$toDataFrame()

表情变成这样:
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>

我尝试使用 R 中的函数 iconv 将其转换,代码如下:
iconv(tweet$text, from="UTF-8", to="ASCII", "byte)

我只设法让它看起来像这样:
<ed><a0><bd><ed><b2><af>

所以,在我的测试结束时,我得到了以下结果:
<ed><a0><bd><ed><b2><af>
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
\xed��\xed��

其中没有一个看起来像表指定的代码点:
U+1F4AF

有没有可能在两个字符串之间进行转换?
我错过了什么?为什么 Twitter 会为表情符号返回此信息?

最佳答案

我之前对编码一无所知,但经过几天的阅读,我想我知道发生了什么。我不完全理解表情符号的编码是如何工作的,但我偶然发现了同样的问题并解决了它。

您想将 \xed��\xed�� 映射到它的名称解码版本:100 点。一种明智的方法是在线抓取字典并使用一个键(例如 Unicode)来替换它。在这种情况下,它将是 U+1F4AF
您显示的转换不是不同的编码,而是相同编码表情符号的不同表示法:

  • as.data.frame(tweet) 返回 <ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
  • iconv(tweet, from="UTF-8", to="ASCII", "byte") 返回 <ed><a0><bd><ed><b2><af>

  • 所以直接使用 Unicode 是不可行的。另一种方法可能是使用已经以 <ed>...<ed>... 方式对表情符号进行编码的字典,就像这里的那样: emoji list 。瞧!只有她的名单不完整,因为它来自
    包含较少表情符号的字典。

    快速解决方案是 简单地抓取更完整的字典并将 <ed>...<ed>... 与其对应的英文文本翻译映射。我已经这样做了, 发布了 here

    尽管没有其他人发布带有正确编码的列表这一事实让我感到烦恼。事实上,我发现的大多数词典都有 UTF-8 编码,使用的不是 <ed>...<ed>... 表示,而是 <f0>... 。事实证明,对于相同的 unicode U+1F4AF,它们都是正确的 UTF-8 编码,只是字节的读取方式不同。

    长答案 。该推文以 UTF-16 读取,然后转换为 UTF-8,这就是转换不同的地方。当读取由字节对完成时,结果将是 UTF-8 <ed>...<ed>... ,当它被四个字节的块读取时,结果将是 UTF-8 <f0>... (这是为什么?我不完全理解,但我怀疑它与处理器的架构有关)。

    因此,解决问题的一种较慢(但更有意识)的方法是抓取 <f0>... 字典,将其转换为 UTF-16,然后成对地将其转换回 UTF-8,最终会得到两个 <ed>... 。这两个 <ed>... 被称为 Unicode U+xxxxx 的低高代理对表示。

    举个例子:
    unicode <- 0x1F4Af
    
    # Multibyte Version
    intToUtf8(unicode)
    
    # Byte-pair Version
    hilo <- unicode2hilo(unicode)
    intToUtf8(hilo)
    

    返回:
    [1] "\xf0\u009f\u0092�"
    [1] "\xed��\xed��"
    

    同样,使用 iconv(..., 'utf-8', 'latin1', 'byte') ,与以下内容相同:
    [1] "<f0><9f><92><af>"
    [1] "<ed><a0><bd><ed><b2><af>"
    

    PS1。 :
    函数 unicode2hilo 是一个简单的 hi-lo 到 unicode 的线性变换
    unicode2hilo <- function(unicode){
       hi = floor((unicode - 0x10000)/0x400) + 0xd800
       lo = (unicode - 0x10000) + 0xdc00 - (hi-0xd800)*0x400
       hilo = paste('0x', as.hexmode(c(hi,lo)), sep = '')
       return(hilo)
    }
    
    hilo2unicode <- function(hi,lo){
       unicode = (hi - 0xD800) * 0x400 + lo - 0xDC00 + 0x10000 
       unicode = paste('0x', as.hexmode(unicode), sep = '')
       return(unicode)
    }
    

    PS2。 :
    我建议使用 iconv(tweet, 'UTF-8', 'latin1', 'byte') 来保留像 áäà 这样的特殊字符。

    PS3。 :
    要将表情符号替换为其英文文本、标签、哈希或任何您想将其映射到的内容,我建议在表情符号图中使用 DFS,因为有些表情符号的 unicode 是其他更简单的 unicodes 的串联(即 <f0><9f><a4><b8><e2><80><8d><e2><99><82><ef><b8><8f> 是一个男人侧手翻,而独立的 <f0><9f><a4><b8> 是人侧手翻,<e2><80><8d> 什么都不是,<e2><99><82> 是一个男性标志,<ef><b8><8f> 什么都不是),而男人侧手翻和人侧手翻男性标志显然在语义上是相关的,我更喜欢更忠实的翻译。

    关于r - twitteR 和 R 的 Twitter 表情符号编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37999896/

    相关文章:

    php - 通过 PHP 使用 XSLT 的 UTF-8 编码问题

    r - table() 行全为零

    javascript - 即使在网站中使用 JavaScript 阻止弹出窗口时如何共享 Twitter

    python - Tweepy - 获取访问 token 时出错 : "argument 2 to map() must support iteration"

    iphone - accountTypeWithAccountTypeIdentifier 未完成

    php - UTF-8 纠正后出现奇怪的编码问题 "most"

    c# - 生成 PHP UTF-16 SHA1 哈希以匹配 C# 方法

    r - 将 ggplot2 图例移动到右上角?

    r - 使用 R-lsa 包计算语义空间中文档之间的余弦相似度

    r - 从 Atlassian Stash 安装 R 包