JS实现HTML实体与字符的相互转换(一)

最近在用Node.js获取网页时发现返回的网页中有一些实体字符,比如中文应该是“用户名”,结果返回的是用户名,读起来相当不爽,于是网上查询能将html实体字符转化为相应字符的方法,找了一些感觉不对症(不知道我是不是没找对地方)。不多幸好知道了实体字符也是相应Unicode字符的再包装,于是自己写了js代码来完成二者之间的相互转换。

不过还是要澄清一下,本文主要讲述的转换不适用于所有的命名实体,如&nbsp;&amp;等,而仅仅是针对实体编号(包括10进制和16进制编码)的,比如“中国”被编码为&#20013;&#22269;的情况。如果让您失望了,在此我深表遗憾。不过,我的另一篇文章JS实现HTML实体与字符的相互转换(二)将主要讲述命名实体同字符的转换,如&lt;<的相互转换,希望能解决您的问题吧。

在讲实体字符与相应字符之前的转换前,首先再来复习一遍charCodeAtformCharCode两个函数。前者是所有字符串共有的方法(定义在String.prototype中),它接收一个参数,可返回指定位置字符的 Unicode 编码,这个返回值是 0 - 65535 之间的整数;后者是String的静态方法,可接受一个或多个指定的 Unicode 值,然后返回一个字符串。好了,知道这两个函数就能完成Unicode值与字符的相互转换了。还是来看代码:

//字符串转字符实体
function stringToEntity(str,radix){
  let arr=[]
  //返回的字符实体默认10进制,也可以选择16进制
  radix=radix||0
  for(let i=0;i<str.length;i++){                               
    arr.push((!radix?'&#'+str.charCodeAt(i):'&#x'+str.charCodeAt(i).toString(16))+';')
  }
  let tmp=arr.join('')
  console.log(`'${str}' 转实体为 '${tmp}'`)
  return tmp
}

这里没什么好讲的,就是用charCodeAt函数把字符串的Unicode码返回再加上实体符号的前缀后缀,拼接就好了。

//字符实体转字符串
function entityToString(entity){
  let entities=entity.split(';')
  entities.pop()
  let tmp=''
  for(let i=0;i<entities.length;i++){
    let num=entities[i].trim().slice(2)
    if(num[0]==='x')//10进制还是16进制
      num=parseInt(num.slice(1),16);
    else num=parseInt(num);
    tmp+=String.fromCharCode(num)
  }
  console.log(`'${entity}' 转字符串为 '${tmp}'`)
  return tmp
}

这个也好理解,提取出给定实体的Unicode字符码,用String.fromCharCode转换为给定的字符就好了。关键把位置找好。

这里用到了一些ES6的语法,比如let和模版字符串(就是写在反引号里面的东西了,减轻了我们拼接字符串的负担)语法。还有后面的箭头函数都是很好的东西,但有时也会踩坑呀。整体思想还是挺简单的,就是字符转Unicode码然后按相应格式拼接就可以了。

然后测试一下效果,嗯,效果还是不错的

let _str=entityToString('&#x7528;&#x6237;&#x540D;&#162;')
entityToString(stringToEntity(_str))
entityToString(stringToEntity(_str,1))
console.log('')
_str=entityToString('&#913;&#914;&#922;')
entityToString(stringToEntity(_str))
entityToString(stringToEntity(_str,1))
/******* the result *******
'&#x7528;&#x6237;&#x540D;&#162;' 转字符串为 '用户名¢'
'用户名¢' 转实体为 '&#29992;&#25143;&#21517;&#162;'
'&#29992;&#25143;&#21517;&#162;' 转字符串为 '用户名¢'
i'用户名¢' 转实体为 '&#x7528;&#x6237;&#x540d;&#xa2;'
'&#x7528;&#x6237;&#x540d;&#xa2;' 转字符串为 '用户名¢'

'&#913;&#914;&#922;' 转字符串为 'ΑΒΚ'
'ΑΒΚ' 转实体为 '&#913;&#914;&#922;'
'&#913;&#914;&#922;' 转字符串为 'ΑΒΚ'
'ΑΒΚ' 转实体为 '&#x391;&#x392;&#x39a;'
'&#x391;&#x392;&#x39a;' 转字符串为 'ΑΒΚ'
**************************/

什么,代码有点low,那好吧,这样呢?这样就简洁多了。

function stringToEntity(str,radix){
  let arr=str.split('')
  radix=radix||0
  let tmp=arr.map(item=>
`&#${(radix?'x'+item.charCodeAt(0).toString(16):item.charCodeAt(0))};`).join('')
  console.log(`'${str}' 转实体为 '${tmp}'`)
  return tmp
}
function entityToString(entity){
  let entities=entity.split(';')
  entities.pop()
  let tmp=entities.map(item=>String.fromCharCode(
  item[2]==='x'?parseInt(item.slice(3),16):parseInt(item.slice(2)))).join('')
  console.log(`'${entity}' 转字符串为 '${tmp}'`)
  return tmp
}

下面给一个HTML实体对照表:
HTML特殊符号对照表、常用的字符实体

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值