获取表情字符串的html,R可以读取html编码的表情符号吗?

2023-11-28 06:10

本文主要是介绍获取表情字符串的html,R可以读取html编码的表情符号吗?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

4 个答案:

答案 0 :(得分:5)

tl; dr:表情符号不是有效的HTML实体;已使用UTF-16编号来构建它们而不是Unicode代码点。我在答案的底部描述了一个算法来转换它们,使它们成为有效的XML。

识别问题

R肯定会处理表情符号:

EsR5D.png

实际上,存在一些用于处理R中的表情符号的包。例如,emojifont和emo包都允许您基于Slack样式的关键字检索表情符号。这只是一个从HTML转义格式中获取源角色的问题,以便您可以转换它们。

xml2::read_xml似乎可以与其他HTML实体一起使用,例如&符或双引号。我查看this SO answer以查看HTML实体是否存在任何特定于XML的约束,并且它们似乎正在存储表情符号。所以我尝试将你的代表中的表情符号代码更改为答案中的表情符号:

body="Hug emoji: 😀😃"

而且,果然,他们被保留了(虽然他们显然不再是拥抱表情符号):

> test8 = read_html('Desktop/test.xml')

> test8 %>% xml_child() %>% xml_child() %>% xml_child() %>% xml_attr('body')

[1] "Hug emoji: \U0001f600\U0001f603"

我在this page上查找了拥抱表情符号,其中给出的十进制HTML实体not 。看起来表情符号的UTF-16十进制代码已包含在和;中。

总之,我认为答案是你的表情符号实际上不是有效的HTML实体。如果您无法控制来源,则可能需要进行一些预处理以解决这些错误。

那么,为什么浏览器会正确转换它们?我想知道浏览器是否对这些东西更灵活,并且正在猜测这些代码可能是什么。不过,我只是在猜测。

将UTF-16转换为Unicode代码点

经过一些调查,看起来有效的表情符号HTML实体使用Unicode代码点(十进制,如果它是...;,或十六进制,如果它是...;)。 The Unicode code point is different from the UTF-8 or UTF-16 code.(该链接解释了关于表情符号和其他字符如何进行各种编码的lot,顺便说一句!好读。)

因此,我们需要将源数据中使用的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并与数据框进行连接,如果您已将表情符号代码提取到列中,则可以获取英文名称。

答案 1 :(得分:1)

将Chad的JavaScript答案翻译为Go,因为我也遇到了同样的问题,但是需要Go中的解决方案。

package main

import (

"fmt"

"html"

"regexp"

"strconv"

"strings"

)

func main() {

emoji := ""

regexp := regexp.MustCompile(`(\d+;){2}`)

matches := regexp.FindAllString(emoji, -1)

var builder strings.Builder

for _, match := range matches {

s := strings.Replace(match, "", "", -1)

parts := strings.Split(s, ";")

a := parts[0]

b := parts[1]

c, err := strconv.Atoi(a)

if err != nil {

panic(err)

}

d, err := strconv.Atoi(b)

if err != nil {

panic(err)

}

c = c - 0xd800

d = d - 0xdc00

e := strconv.FormatInt(int64(c), 2)

f := strconv.FormatInt(int64(d), 2)

g := "0000000000"[2:len(e)] + e

h := "0000000000"[10:len(f)] + f

j, err := strconv.ParseInt(g + h, 2, 64)

if err != nil {

panic(err)

}

k := j + 0x10000

_, err = builder.WriteString("" + strconv.FormatInt(k, 16) + ";")

if err != nil {

panic(err)

}

}

fmt.Println(html.UnescapeString(emoji))

emoji = html.UnescapeString(builder.String())

fmt.Println(emoji)

}

答案 2 :(得分:1)

我在R中实现了算法described by rensa above,并在此处分享。

这是rensa算法的快速和未经修改的实现,但它可以工作!

{'Name':'value',

'Address': 'value'

}

答案 3 :(得分:0)

JavaScript解决方案

我遇到了这个exact相同的问题,但是需要JavaScript而不是R中的解决方案。在上方使用@rensa's comment(非常有帮助!)< / em>,我创建了以下代码来解决此问题,我只是想共享它,以防其他人像我一样跨此线程发生,但是在JavaScript中需要它。

str.replace(/(\d+;){2}/g, function(match) {

match = match.replace(//g,'').split(';');

var binFirst = (parseInt('0x' + parseInt(match[0]).toString(16)) - 0xd800).toString(2);

var binSecond = (parseInt('0x' + parseInt(match[1]).toString(16)) - 0xdc00).toString(2);

binFirst = '0000000000'.substr(binFirst.length) + binFirst;

binSecond = '0000000000'.substr(binSecond.length) + binSecond;

return '' + (('0x' + (parseInt(binFirst + binSecond, 2).toString(16))) - (-0x10000)).toString(16) + ';';

});

并且,如果您想运行它,这是一个完整的代码片段:

var str = ''

str = str.replace(/(\d+;){2}/g, function(match) {

match = match.replace(//g,'').split(';');

var binFirst = (parseInt('0x' + parseInt(match[0]).toString(16)) - 0xd800).toString(2);

var binSecond = (parseInt('0x' + parseInt(match[1]).toString(16)) - 0xdc00).toString(2);

binFirst = '0000000000'.substr(binFirst.length) + binFirst;

binSecond = '0000000000'.substr(binSecond.length) + binSecond;

return '' + (('0x' + (parseInt(binFirst + binSecond, 2).toString(16))) - (-0x10000)).toString(16) + ';';

});

document.getElementById('result').innerHTML = str;

//

// is turned into

// 😊😘😀😆😂😁

// which is rendered by the browser as the emojis

Original:

Result:

我的SMS XML Parser应用程序现在运行良好,但是在大型XML文件上停滞了,因此,我正在考虑用PHP重写它。如果/当我这样做的话,我也会张贴该代码。

这篇关于获取表情字符串的html,R可以读取html编码的表情符号吗?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/429185

相关文章

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

python中os.stat().st_size、os.path.getsize()获取文件大小

《python中os.stat().st_size、os.path.getsize()获取文件大小》本文介绍了使用os.stat()和os.path.getsize()函数获取文件大小,文中通过示例代... 目录一、os.stat().st_size二、os.path.getsize()三、函数封装一、os

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情