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

来源:互联网 发布:mpp 文件查看 mac 编辑:程序博客网 时间:2024/06/03 08:20

最近在用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特殊符号对照表、常用的字符实体

原创粉丝点击