U+200B (Zero Width Space)

今天在在把 pdf 文件里的内容转化成字符串的过程中,遇到一个正则匹配问题,明明觉得表达式是没问题的,但就是匹配不出结果,原因是将u200B当做了空格来处理了。具体问题该链接 (opens in a new tab)

主要记录这几个问题:

  1. u+200B是什么,他的作用是什么?
  2. unicode 具体是什么以及产生背景?
  3. utf8 是什么,他和utf16、utf32有何区别,转化的意义是什么?

U+200B

是什么

U+200B (Zero Width Space) 是一个零宽度的空格,用于在英文单词中间插入空格,以避免英文单词被分割成两行。

怪异表现

他在 JS 中挺有迷惑性的,看下面代码:

const str = '\u200B'
console.log(str) // ''
console.log(str.length) // 1

更奇怪的是:复制上面那个空字符串,再粘贴到浏览器中,他的显示并不是空字符串,而是一个红点,所以在 debug 过程中也比较难察觉。

1673881886544.png

遇到这个问题,我脑子第个想法是:肯定是解析 pdf 时,字符编码出现了兼容问题,但即使我在输出文本的过程中转化了utf8之后,这个问题依然存在。从 stackoverflow (opens in a new tab) 的回答来看,我对这个\u200B 这个长相,以及我之前无脑转化了uft8后,觉得对他们的关联感到更加迷惑,引申出来我对 utf8unicode 之间的关系也有一定混淆。

所以有必要了解一下两者之间的关系和历史,其实讲一下它的历史就明白他俩的区别了,因为历史就是一切的根源。

unicode背景

unicode是字符集,什么是字符集,就是字符映射成二进制的一个集合,因为计算机不认识字母,只认识数字(二进制),我们输入的 A,要转化成65(0100 0001),这个过程就是字符集的作用。 ASCII码耳熟能详,它就是最原始的字符集。为什么原始,因为它只映射了英文字符还有一些特殊符号,ASCII码字符集 (opens in a new tab) 都在这了 。

ascii.png

所以问题来了:我们在展示文字上,如果遇到中文、可能会出现乱码,因为ASCII字符集里没有中文的映射。如何解决?扩充呗,GBK、GB2312、BIG5等等,这些都是为了中文等之前没有的字符,进行扩充的字符集,目的都是为了解决中文等乱码问题。如下图所示:

gbk.png

所以问题来了:除了中文,还有日文韩文阿拉伯文...如果不进行统一,都会有乱码的问题,所以就有了 unicode,它是一个统一的字符集,它将世界上所有的字符都映射到了 unicode 中,这样就不会出现乱码的问题了!

unicode 与 utf8

unicode统一了所有字符集,就代表他是一个很大的映射表,以怎么样的方式去储存?比如刚才说的A就映射成65,一共就256个字符,那我就可以用一个字节就可以存储了,但是一个中文汉字,可能就不够。为了不造成资源的浪费,动态的规则显得尤为重要,这个规则就是utf8。具体规则 https://www.zhihu.com/question/23374078/answer/24385963 (opens in a new tab)

utf8 与 utf16/32

那紧接着问题又从脑子中闪现出一个新疑惑,utf8转utf16之类的操作的目的是什么? https://stackoverflow.com/a/5292180/10517346 (opens in a new tab) 这个回答解释的很清楚,utf8是为了节省空间,utf16是为了节省时间。就像是算法的时间和空间复杂度一样,特定的场景下,根据场景去选择合适的算法,这样才能达到最优的效果。

结论

所以结论是把生成的字符串转成 utf8 这个操作完全没有意义。映射出来的\u200B还是那个长度为1的特殊空字符串,解决的办法是正则上对 \u200B 也做处理。

u+200B存在的意义是什么

虽然解决了问题,但还是要了解下他存在的价值以及用途是什么。

<p>中文 &#x200b; English</p>

参考文章: