Unicode笔记

1. Unicode是什么?

有一个想法,将全世界所有的字符号都包含在一个集合里边,任何机器支持这一个集合就行了,再也不会有乱码了。基于这个想法,Unicode码应运而生。它用数字编号来表示符号,到7.0版,已经有了109449个符号。一般用26进制表示,’U+4E49’表示字符’义’,’U+’是前缀,整体叫做码点
集合分为几个区间,U+0000~U+FFFF是最常用的字符,称为基本平面,剩下的U+010000~U+10FFFF称为辅助平面

2. 编码方式

平常说的UTF-8,UTF-16就是说的码点的编码方式。UTF-32指无论是什么码点,一律使用4个字节表示,一共是8位16进制数,位数不足的,在前边补0,例如U+389D = 0x0000 389D。UTF-8字节数灵活,用1个字节能表示的用1个字节,用两个字节才能表示的,用两个字节,还可能是3个4个字节。同样的文本UTF-8占的存储空间比UTF32小多了。所以,网页编码大部分使用的是UTF-8。

3. UTF-16

重点说一下UTF-16。UTF-16介于以上两者之间,规则也很简单,基本平面的字符占用2个字节,辅助平面的字节占用4个字节。因为常用的字符都在基本平面,所以UTF-16比UTF-32所占空间要小。当我们看到4个字节,如果前两个字节码点的范围是U+D800到U+DBFF,那么后两个字节码点一般在U+DC00到U+DFFF范围内,那么它就是一个4字节字符。但是U+D800到U+DBFF范围内的2个字节的字符怎么办?在基本平面里边U+D800~U+DBFF是一个空段,不对应任何字符(不知道是不是有意为之),所以用这段来表示4字节字符的前段,也叫高位,后边的U+DC00到U+DFFF叫低位。

所以,当我们遇到两个字节,发现它的码点在U+D800到U+DBFF之间,就可以断定,紧跟在后面的两个字节的码点,应该在U+DC00到U+DFFF之间,这四个字节必须放在一起解读。

给一个辅助平面的码点,怎么转化成UTF-164字节形式呢?有一个公式可用:

H = Math.floor((c - 0x10000) / 0x400) + 0xD800
L = (c - 0x10000) % 0x400 + 0xDC00

4. javascript中的Unicode

javascript采用Unicode字符集,支持的编码方式是UCS-2。UTF-16是UCS-2的超集,至于UCS-2是什么,请自行百度。在javascript中处理字符串时,可以看做是UTF-16编码。遇到4个字节的字符,String.prototype.length会得到2,不过在es6中增加了新的api处理4个字节字符的方法,这里就不展开介绍了。js中的表示方法是’\u’+四位16进制数,例如’\u4f60’表示中文’你’,这是一个长度是1的字符。’\u004F\u030C’表示符号’Ǒ’,lendth长度是2。匹配辅助平面的字符的正则:/[\uD800-\uDBFF][\uDC00-\uDFFF]/,匹配到的字符length都是2。首先要将码点转化为高位和低位形式,再与正则比较判断。

5. javascript中处理emoji

emoji实质上也是Unicode码,也可以在javascript中处理。大部分emoji是4个字节,由高位+低位两端编码组成,只要解析的时候不把高位和低位分开,就不会出现’乱码’的情况。但是有些emoji是由多个emoji连接而成,例如:

U+1F468:男人
U+1F469:女人
U+1F467:女孩

使用连接符号U+200D连接,U+1F468 U+200D U+1F469 U+200D U+1F467,就会显示一个新的emoji表情:家庭,但是如果系统不支持这种表示,还是会显示3个单独的表情。