&#x的实体编码解释

转载自https://www.cnblogs.com/philipding/p/10153094.html

本博客仅为学习记录,如有侵权,请联系作者删除

在 Node 层利用 cheerio 解析网页时,输出的中文内容都是以 &#x 开头的一堆像乱码一样的东西,尝试过各种编码都无效,而且神奇的是,将这一堆“乱码”保存成网页后,通过浏览器打开又可以正常显示。这到底是什么????

缩减后的示例代码如下:

const cheerio = require(‘cheerio‘);
const $ = cheerio.load(‘<div id="content">你好</div>‘)
console.log($(‘#content‘).html()) //&#x4F60;&#x597D;
其实,上面那一堆乱码一样的东西,它的学名叫实体编码 entity code。

下面引用下知乎搜到的答案。

在 HTML 中,某些字符是预留的,例如小于号「<」、大于号「>」等,浏览器会将它们视作标签。如果想要在HTML中显示这些预留字符,我们就要用到字符实体(character entities)。我们比较熟悉的字符实体有空格「&nbsp;」,小于号「&lt;」,大于号「&gt;」等。这样的格式比较语义化,容易记忆,但其实字符实体有其他的格式:

&name;
&#dddd;
&#xhhhh;
这三种转义方式都称作 character reference,第一种是 character entity reference,「&」符号后接预先定义好的 entity 名称。
后两种是 numeric character reference,数字取值为目标字符的 Unicode code point;以「&#」开头的后接十进制数字,「&#x」开头的后接十六进制数字。
从 HTML4 开始,numeric character reference 以 Unicode 为准,与文档编码无关。「你好」二字分别是 Unicode 字符 U+4F60 和 U+597D,十六进制表示的 code point 数值「4F60」和「597D」,同时也就是十进制的「20320」和「22909」。所以

在HTML中输入

&#x4F60;&#x597D;
&#20320;&#22909;
都会显示为“你好”。

知道原因后,那么如何解决上述的问题呢?

方法一:使用cheerio提供的属性

cheerio默认会对entity进行decode,我们只需要关闭该功能即可

const cheerio = require(‘cheerio‘);
const $ = cheerio.load(‘<div id="content">你好</div>‘, { decodeEntities: false })
console.log($(‘#content‘).html()) // 你好
方法二:手动decode

function decode(str) {
    // 一般可以先转换为标准 unicode 格式(有需要就添加:当返回的数据呈现太多\\\u 之类的时)
    str = unescape(str.replace(/\\u/g, "%u"));
    // 再对实体符进行转义
    // 有 x 则表示是16进制,$1 就是匹配是否有 x,$2 就是匹配出的第二个括号捕获到的内容,将 $2 以对应进制表示转换
    str = str.replace(/&#(x)?(\w+);/g, function($, $1, $2) {
      return String.fromCharCode(parseInt($2, $1? 16: 10));
    });

    return str;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值