R能读懂html编码的表情符号吗? [英] Can R read html-encoded emoji characters?
问题描述
问题
我的问题解释如下:如何使用R来读取包含
��
这样的HTML表情代码的字符串?我想:
(1)在解析后的字符串中表示表情符号(例如,作为Unicode符号:
🤗
),或(2)将其转换为对应的文本("
:hugging face:
")
背景
我有一个文本消息的XML数据集(来自Android/iOS应用程序Signal),我正在为一个文本挖掘项目将其读入R。数据如下所示,每条文本消息都在sms
节点中表示:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!-- File Created By Signal -->
<smses count="1">
<sms protocol="0" address="+15555555555" contact_name="Jane Doe" date="1483256850399" readable_date="Sat, 31 Dec 2016 23:47:30 PST" type="1" subject="null" body="Hug emoji: ��" toa="null" sc_toa="null" service_center="null" read="1" status="-1" locked="0" />
</smses>
问题
我当前正在使用R的xml2
包读取数据,但是,当我使用xml2::read_xml
函数时,我收到以下错误消息:
Error in doc_parse_raw(x, encoding = encoding, base_url = base_url, as_html = as_html, :
xmlParseCharRef: invalid xmlChar value 55358
据我所知,这表示该表情符号未被识别为有效的XML。
使用xml2::read_html
函数可以工作,但会删除表情符号。下面是一个小例子:
example_text <- "Hugging emoji: ��"
xml2::xml_text(xml2::read_html(paste0("<x>", example_text, "</x>")))
(输出:[1] "Hugging emoji: "
)
此字符是有效的HTML--Google��
实际上会在搜索栏中将其转换为"拥抱脸"表情符号,并显示与该表情符号相关的结果。
我发现的其他似乎与此问题相关的信息
我一直在搜索堆栈溢出,没有发现任何与此特定问题相关的问题。我也找不到一个在它们所代表的表情符号旁边直接提供HTML码的表,因此在解析数据集之前,无法在大循环中将这些HTML码转换为它们的文本等效项;例如,this list和its underlying dataset似乎都不包括字符串55358
。
utf
tl;dr:表情符号不是有效的推荐答案实体;已使用UTf-16数字来构建它们,而不是使用unicode代码点。我在答案的底部描述了一个算法来转换它们,使它们成为有效的XML。
确定问题
R肯定会处理表情符号:
事实上,在R中存在一些用于处理emoji的包。例如,emojifont和emo包都可以让您基于Slack风格的关键字检索emoji。这只是一个问题,让您的源字符通过的HTML转义格式,以便您可以转换它们。xml2::read_xml
似乎可以很好地处理其他HTML实体,如与号或双引号。我看了看this SO answer,看看是否有任何特定于XML的限制对HTML实体,看起来他们很好地存储了表情符号。所以我试着把你的表情包中的表情代码改成了答案中的表情符号代码:
body="Hug emoji: 😀😃"
果然,它们被保存了下来(尽管它们显然不再是拥抱的表情符号):
> test8 = read_html('Desktop/test.xml')
> test8 %>% xml_child() %>% xml_child() %>% xml_child() %>% xml_attr('body')
[1] "Hug emoji: U0001f600U0001f603"
我在this page上查找了拥抱表情符号,那里给出的十进制HTML实体是NOT��
。表情符号的UTF-16十进制代码看起来已经包含在&#
和;
中。
那么,为什么浏览器可以正确地转换它们?我想知道浏览器对这些东西是否更灵活一些,并正在猜测这些代码可能是什么。不过,我只是在猜测。
将UTF-16转换为Unicode码位
经过进一步调查,看起来有效的emoji HTML实体使用Unicode代码点(如果&#...;
为十进制,如果&#x...;
则为十六进制)。The Unicode code point is different from the UTF-8 or UTF-16 code.(该链接解释了很多表情符号和其他字符是如何编码的,顺便说一句!读得好。)
因此,我们需要将源数据中使用的UTF-16代码转换为Unicode代码点。参考this Wikipedia article on UTF-16,我已经验证了它是如何完成的。每个Unicode代码点(我们的目标)都是一个20位的数字,或五个十六进制数字。当从Unicode转换为UTF-16时,您将它分成两个10位数字(中间的十六进制数字被一分为二,其中两个位分配给每个块),对它们进行一些数学运算,得到结果)。
如您所愿,它是这样做的:
- 您的十进制UTF-16数字(目前在两个单独的块中)是
55358 56599
- 将这些块(分别)转换为十六进制得到
0x0d83e 0x0dd17
- 从第一块中减去
0xd800
,从第二块中减去0xdc00
得到0x3e 0x117
- 将它们转换为二进制,填充为10位,然后将它们连接起来,这是
0b0000 1111 1001 0001 0111
- 然后我们将其转换回十六进制,即
0x0f917
- 最后,我们添加
0x10000
,给出0x1f917
- 因此,我们的(十六进制)HTML实体是
🤗
。或者,以十进制表示🤗
因此,要对此数据集进行预处理,您需要提取现有数字,使用上面的算法,然后将结果放回(使用一个&#...;
,而不是两个)。
在R中显示表情符号
据我所知,在R控制台中打印表情符号没有解决方案:它们总是以"U0001f600"
(或者你有什么)的形式出现。然而,我上面描述的包可以在某些情况下帮助你绘制表情符号(我希望扩展ggflags,在某个时候显示任意的全色表情符号)。他们还可以帮助你搜索表情符号来获得他们的代码,但他们不能获得代码为AFAIK的名字。但也许你可以尝试将the emoji list from emojilib
导入R中,并与你的数据框进行连接,如果你已经将表情代码提取到一列中,那么就可以得到英文名字。
这篇关于R能读懂html编码的表情符号吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!