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

Ed.*_*Ed. 5 twitter encoding r utf-8 emoji

我正在尝试构建一种在twitter中查找表情符号的方法,并将它们与unicode表中可以找到的unicode表联系起来,但我发现很难识别它们,因为我认为编码问题或仅仅是我对它的误解.这个话题.简而言之,我所做的是从http://www.unicode.org/emoji/charts/full-emoji-list.html中的表格中构建一个表情符号"库",其中包含标题和代码点(代码表情符号.我在R里用图书馆rvest取消了这个.

问题出现在我用推特中的twitteR API从twitter获取信息时.因为表情符号的代码看起来并不像这个表中的那些.

让我们举一个100(100点)红色图标表情符号的例子.这是前链接表中的数字1468,其代码点代码为:

U+1F4AF
Run Code Online (Sandbox Code Playgroud)

现在,当我从twitter中获取它时,首先它在状态类中显示为这样,API已内置以使用推文.

\xed??\xed??
Run Code Online (Sandbox Code Playgroud)

然后,一旦我将其转换为数据帧,我也使用来自twitter API的内置函数.例如:

tweet$toDataFrame()
Run Code Online (Sandbox Code Playgroud)

表情符号变为:

<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
Run Code Online (Sandbox Code Playgroud)

我尝试使用R中的函数iconv将其转换为以下代码:

iconv(tweet$text, from="UTF-8", to="ASCII", "byte)
Run Code Online (Sandbox Code Playgroud)

我只设法使它看起来像这样:

<ed><a0><bd><ed><b2><af>
Run Code Online (Sandbox Code Playgroud)

因此,结束并在测试结束时,我得到以下结果:

<ed><a0><bd><ed><b2><af>
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
\xed??\xed??
Run Code Online (Sandbox Code Playgroud)

其中没有一个看起来像表格指定的代码点:

U+1F4AF
Run Code Online (Sandbox Code Playgroud)

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

小智 9

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

您想要映射\xed??\xed??到其名称解码版本:百分.一种明智的方法可能是在线刮取字典并使用诸如Unicode之类的密钥来替换它.在这种情况下,它会U+1F4AF.您显示的转换不是不同的编码,而是针对相同编码表情符号的不同表示法:

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

因此直接使用Unicode是不可行的.另一种方法是使用一个字典,它已经<ed>...<ed>...按照这里的方式编写表情符号:表情符号列表.瞧!只有她的列表不完整,因为它来自包含较少表情符号的字典.

快速解决方案是简单地刮取更完整的字典并<ed>...<ed>...使用相应的英文文本翻译进行映射.我已经这样做并发布 在这里.

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

答案很长.推文以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)
Run Code Online (Sandbox Code Playgroud)

返回:

[1] "\xf0\u009f\u0092?"
[1] "\xed??\xed??"
Run Code Online (Sandbox Code Playgroud)

再次使用iconv(..., 'utf-8', 'latin1', 'byte'),与以下相同:

[1] "<f0><9f><92><af>"
[1] "<ed><a0><bd><ed><b2><af>"
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

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

PS3.:要与它的英文文本,标签,哈希,或任何更换表情符号要映射它,我会在表情符号的图形使用DFS,因为有一些表情符号,它的unicode是其他简单统一码的级联提示(即<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>没有什么)而男人车轮人车轮男性标志显然是语义相关的,我更喜欢更忠实的翻译.