每个 JavaScript 开发者都该懂的 Unicode
英文原文标题:what-every-javascript-developer-should-know-about-unicode
(译者注:本文含有Unicode辅助平面的特殊字符,部分浏览器可能无法正确显示,但并不影响理解文章内容。)
在动笔写这篇文章之前,我得先忏悔一下:在很长一段时间里我对Unicode充满了恐惧。
每次遇到需要Unicode知识的编程问题时,我总是找一个hack方案来解决,但解决方案的原理我也不懂。
直到遇见一个需要深入了解Unicode知识才能解决的问题,我才停止了这种逃避。因为这个问题没办法应用特定情境的解决方案。
在努力读了一大堆文章之后,我惊讶地发现Unicode并不难懂。好吧,确实是有些文章起码得看3遍才能看懂。
但我发现Unicode标准不仅世界通用,而且十分优雅简洁,只不过要理解其中一些抽象概念有点困难。
如果你觉得理解Unicode很难,那么是时候来面对它了!其实它没你想的那么难。去沏一杯香浓的茶或咖啡吧,让我们进入抽象概念、字符、星光平面(辅助平面)和代理对的世界。
本文首先会解释Unicode中的基本概念,这是必需的背景知识。
然后会说明JavaScript如何解析Unicode,以及你可能踩到哪些坑。
你还会学到如何利用ECMAScript 2015的新特性来解决部分难题。
准备好了?那就燥起来吧!
目录:
1 Unicode背后的思想
2 Unicode基本概念
- 2.1 字符与代码点
- 2.2 Unicode平面
- 2.3 码元
- 2.4 代理对
- 2.5 组合用字符
3 JavaScript中的Unicode
- 3.1 转义序列
- 3.2 字符串比较
- 3.3 字符串长度
- 3.4 字符定位
- 3.5 正则匹配
4 结语
1. Unicode背后的思想
首先问一个最基础的问题:你是怎样阅读并理解这篇文章的?答案很简单,因为你明白这些字以及由字组成的单词的含义。
那你又是如何明白这些字的含义的呢?答案也很简单,因为你(读者)和我(作者)对于这些(呈现在屏幕上的)图形与汉字(即含义)之间的联系有着相同的认知。
对计算机来说这个原理也差不多,只有一点不同:计算机不懂这些字(字母)的含义,只是将其理解为特定的比特序列。
让我们设想一个情景:计算机User1向计算机User2发送一条消息'hello'。
计算机并不知道这些字母的含义。所以计算机User1将消息'hello'转换为一串数字序列0x68 0x65 0x6C 0x6C 0x6F,每个字母对应一个数字:h对应0x68, e对应0x65,等等。
接着将这些数字发送给计算机User2。
计算机User2收到数字序列0x68 0x65 0x6C 0x6C 0x6F后,使用同一套字母与数字的对应关系重建消息内容,'hello'就能正确地显示出来了。
不同计算机之间对字母与数字之间对应关系的协议就是Unicode进行标准化的结果。
根据Unicode,h是一个名为LATIN SMALL LETTER H的抽象字符。这个抽象字符对应数字0x68,也就是一个标记为U+0068的代码点。这些概念将在下一章中说明。
Unicode的作用就是提供一个抽象字符列表(字符集),并给每一个字符分配一个独一无二的标识符代码点(编码字符集)。
2. Unicode基本概念
Unicode为每一个字符分配一个专有的数字
不分平台
不分程序
不分语言
Unicode是一个世界通用的字符集,它定义了全世界大部分书写体系的字符集,并为每一个字符分配了一个独一无二的数字(代码点)。
Unicode囊括了大部分现代语言、标点符号、附加符号(变音符)、数学符号、技术符号、箭头和表情符号等。
Unicode第一版1.0于1991年10月发布,包含7161个字符。最新版9.0(2016年6月发布)则提供了128172个字符的编码。
Unicode的通用性与开放性解决了过去一直存在的一个问题:供应商们各自实现不同的字符集和编码规则,很难处理。
创建一个支持所有字符集和编码规则的应用是十分复杂的。更不用说你选用的编码可能不支持所有你需要的语言。
如果你觉得Unicode很难,那就想想如果没有它编程会更难。
我还记得从前随机选择所需的字符集和编码规则去读取文件内容的时候。全靠人品啊!
2.1 字符与代码点
- 抽象字符(即文本字符)是用来组织、管理或表现文本数据的信息单位。
Unicode中的字符是一个抽象概念。每一个抽象字符都有一个对应的名称,例如LATIN SMALL LETTER A。该抽象字符的图像表现形式(glyph)是a。(译者注:glyph即图像字符)
- 代码点是指被分配给某个抽象字符的数字
代码点以U+的形式表示,U+是代表Unicode的前缀,而是一个16进制数。例如U+0041和U+2603都是代码点。
代码点的取值范围是从U+0000到U+10FFFF。
记住代码点就是一个简单的数字。思考有关Unicode的问题时要记得这一点。
代码点就好像数组元素的下标。
Unicode的神奇之处就在于将代码点与抽象字符关联起来。例如U+0041对应的抽象字符名为LATIN CAPITAL LETTER A (表现为A),而U+2603对应的抽象字符名为SNOWMAN(表现为)
注意,并非所有的代码点都有对应的抽象字符。可用的代码点有114112个,但分配了抽象字符的只有128237个。
2.2 Unicode平面
- 平面是指从U+n0000到U+nFFFF的区间,也就是65536(1000016)个连续的Unicode代码点,n的取值范围是从016到1016。
这些平面将Unicode代码点分为17个大小相等的集合:
基本多文种平面
平面0比较特殊,被称为基本多文种平面或简称BMP。它包含了大多数现代语言的字符 (基本拉丁字母, 西里尔字母, 希腊字母等)和大量的符号。
如上文所述,基本多文种平面的代码点取值范围是从U+0000到U+FFFF,最多可以有4位16进制数字。
大多数时候开发者处理的都是BMP中的字符。它包含了大多数情况下的必需字符。
BMP中的一些字符:
- e对应代码点U+0065 抽象字符名: LATIN SMALL LETTER E
- |对应代码点U+007C 抽象字符名: VERTICAL BAR
- ■对应代码点U+25A0 抽象字符名: BLACK SQUARE
- 对应代码点U+2602 抽象字符名: UMBRELLA
星光平面
BMP之后的16个平面(平面1,平面2,…,平面16)被称为星光平面或辅助平面。
星光平面的代码点被称为星光代码点。这些代码点的取值范围是从U+10000到U+10FFFF。
星光代码点可能会有5位或6位16进制数字:U+ddddd或U+dddddd。
来看几个星光平面里的字符:
最后更新:2017-06-30 17:01:54
上一篇:
企业安全:从触觉时代到视觉时代
下一篇:
我是花肉,想站得高点,看到更多同类,也让更多同类看到我