zoukankan      html  css  js  c++  java
  • 了解Unicode编码

    一. Unicode是什么?

    Unicode是一种字符编码方案,它为每种语言中的每个字符都设定了统一唯一的二进制编码。以实现跨语言、跨平台进行文本转换。

    Unicode是为了解决传统字符编码方案的局限而产生的。

    Unicode编码的发展及详细介绍可以看这篇文章(https://www.php.cn/js-tutorial-414753.html)。

    Unicode字符编码是用一个码位映射一个字符,码位值的范围是从 U+0000 到 U+10FFFF。

    码位:一般是被格式化为十六进制数字的,零填充至少四位数,格式为 U + 前缀。

    比如 A的码位:U+0041, a的码位:U+0061;

    因为A的ASCII十进制为 65; a的ASCII的十进制为97; 我们可以在chrome浏览器下测试下即可:

    'A'.charCodeAt(); // 打印65

    因此 字符 A 十进制为65,转换成十六进制就是41了,十六进制转十进制的方法为 65 = 4 * 16 + 1; 因此变成Unicode码位的话: U+0041了。

    Unicode最前面的65536个字符位,称为零号平面,它的码位范围是从 U+0000 到 U+FFFF; 我们最常见的字符都在这里面了。

    Unicode转义

    1. 16进制转义

    "A" 转义为:'x41'; "a" 转义为: 'x61';

    2. Unicode转义

    A的Unicode码位为: 'U+0041'; 因此 字符A的Unicode的转义就变成了 'u0041'; 我们可以在chrome控制台打印下就知道了。

    在ECMAScript6中,引入了一种新的转义序列:Unicode码位转义: 比如:'u{41}'; 使用大括号对16进制数字,在大括号之间可以使用最多6个十六进制数字。

    字符串方法中的Unicode

    1. String.fromCharCode()

    String.fromCharCode() 方法可以将一个码位转换为字符,但是它只适用于BMP范围内的码位(即从 U+0000 到 U+FFFF)。如果将它用于转换超过BMP外的码位,将不会得到想要的结果。

    fromCharCode()可以接受一个指定的Unicode的值,然后返回一个字符串。该方法是String的静态方法,字符串中的每个字符都由单独的Unicode数字编码指定。基本语法如下所示:

    String.fromCharCode(n1, n2, ......nx);

    比如如下代码:

    var n = String.fromCharCode(72,69,76,76,79); 
    console.log(n); // 打印的值为:"HELLO"

    String.fromCharCode() 的缺点是:

    对于在 U+0000 到 U+FFFF 范围之外的码位是获取不到结果的,我们看下:

    String.fromCharCode(0x1F4A9);

    打印的结果如下:

    解决的方法当然也有,但是方法也不是很好,但是幸运的是,ES6中引入了 String.fromCodePoint(codePoint). 该方法的优点是可以用于任何的Unicode编码,它是范围更广,是从 U+0000 到 U+10FFFF; 我们可以继续使用该方法测试下上面的demo;

    String.fromCodePoint(0x1F4A9);

    在chrome浏览器下执行的结果如下所示:

    2. String.prototype.charAt(position)

    该方法是用来检索包含字符串中的第一个字符。

    比如如下代码:

    'abcdeb'.charAt(1); // 打印 b

    3. String.prototype.charCodeAt(position)

    该方法的含义是:从字符串中获取码位, 检索字符串中第一个字符的码位。

    比如如下代码:

    'ABC'.charCodeAt(1); // 输出结果为66;

    如上是字符串 'ABC'; 找到第2个字符串的码位。

    二:JS中Unicode编码与String相互转换

    1. 字符串转Unicode

    第一种方式:

    var str='u6211u662fu4e2du56fdu4ebaChina';
    var ret1 = eval("'" + str + "'");
    console.log(ret1); // 打印出:我是中国人China

    第二种方式:

    var str='u6211u662fu4e2du56fdu4ebaChina';
    var ret2 = (new Function("return '" + str + "'"))();
    console.log(ret2); // 打印出:我是中国人China

    第三种方式:

    var str='u6211u662fu4e2du56fdu4ebaChina';
    var ret3 = unescape(str.replace(/u/g, '%u'));
    console.log(ret3); // 打印出:我是中国人China

    2. Unicode转字符串

    function string2unicode(str) {
      var html = '';
      for (let i = 0; i < str.length; i++) {
          console.log(str.charCodeAt(i))
        html += "\u" + str.charCodeAt(i).toString(16);
      }
      return html;
    }
    var str = "我是中国人";
    var s2u = string2unicode(str);
    console.log(s2u); // 打印出: u6211u662fu4e2du56fdu4eba
    console.log(eval("'"+s2u+"'")); // 输出:我是中国人

    如上代码,使用的语法是:number.toString(radix);

    radix参数可选;它值可以是2、8、16,表示以多少进制来显示。
    更多了解可以看对应的API(https://www.runoob.com/jsref/jsref-tostring-number.html)

    如下代码演示:

    var num = 15;
    var a = num.toString();
    var b = num.toString(2);
    var c = num.toString(8);
    var d = num.toString(16);
    
    console.log(a); // 15
    console.log(b); // 1111
    console.log(c); // 17
    console.log(d); // f

    如上字符串转Unicode的方法 string2unicode 有缺陷的,比如中文里面包含英文的话,就不行了,请看如下代码:

    function string2unicode(str) {
      var html = '';
      for (let i = 0; i < str.length; i++) {
        html += "\u" + str.charCodeAt(i).toString(16);
      }
      return html;
    }
    var str = "我是中国人a"; 
    var s2u = string2unicode(str);
    console.log(s2u); // 打印结果为: u6211u662fu4e2du56fdu4ebau61
    console.log(eval("'"+s2u+"'"));

    如上代码就报错了,因为JS自身的Unicode转字符串不能识别不足4位的unicode。因此我们要对 string2unicode方法改进一下。

    function string2unicode(str) {
      var html = '';
      var rets = '';
      for (let i = 0; i < str.length; i++) {
          // 获取码位
        var c1 = str.charCodeAt(i);
        // 转换成16进制
        var c16 = c1.toString(16);
        // 0xf 代表16进制f,转换成10进制就是15
        if (c1 < 0xf) {
          html += "\u" + "000" + c16;
        } else if (c1 < 0xff) { 
          html += "\u" + "00" + c16;
        } else if (c1 < 0xfff) {
          html += "\u" + '0' + c16;
        } else {
          html += "\u" + c16;
        }
      }
      rets += html;
      return rets;
    }
    
    var str = "我是中国人a"; 
    var s2u = string2unicode(str);
    console.log(s2u); // 打印结果为: u6211u662fu4e2du56fdu4ebau61
    console.log(eval("'"+s2u+"'")); // 打印: 我是中国人a

    我们可以在chrome控制台看下打印信息如下:

  • 相关阅读:
    mongodb复制集搭建
    mongodb分片集群搭建
    mongodb安装、运行
    吉他“和弦”是什么?
    NoSQL 简介
    淘汰算法 LRU、LFU和FIFO
    Java遍历Map对象的四种方式
    终于搞懂了shell bash cmd...
    如何为openwrt生成补丁
    linux内核启动时报错ubi0 error: validate_ec_hdr: bad data offset 256, expected 128
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/11986125.html
Copyright © 2011-2022 走看看