作者:yixianliu | 来源:互联网 | 2023-10-13 10:22
简介字符编码、字符长度毛病、截取字符毛病、UTF8、Unicode计算机重重底层之下都是由0和1组合,然则你晓得他们是怎样一步步变成字符串的嘛?在我们实际生活中最罕见的例子能够经由
简介
字符编码、字符长度毛病、截取字符毛病、UTF8、Unicode
计算机重重底层之下都是由 0 和 1 组合,然则你晓得他们是怎样一步步变成字符串的嘛?在我们实际生活中最罕见的例子能够经由过程 wo
在新华字典中找到 我
这个字。一样计算机经由过程 0 和 1 组合在 字典
中查找到对应的字符,那 字典
内容是什么呢?
劈头
计算机降生于 美国
它的运用者大多数运用英文,美国国家标准学会
便制订了这本字典
包含了 26个大写英笔墨母
、26个小写英笔墨母
、10个阿拉伯数字
等统共 256
个字符的 ASCII 字符集。
杂沓
ASCII 用二进制来示意就是 0000 0000
到 1111 1111
被用得满满当当,汉字就没有处所能够放得下了这下怎样办?正所谓山河大有人材出,国标编码 GB
系列涌现了,个中最耳熟能详的就是 GB2312
。
那末题目来了天下具有 2500
至 3500
种言语,有笔墨的言语有 930 种。你能设想你在阅读差别言语界面的时刻,须要本身不停的去切换 字典
而且 每次切换查找不到的字符就会乱码
涌现。
一致
书同文,车同轨,行同伦。
上面这句话讴歌了秦始王具有跨时期意义的造诣,然则实际天下中一致言语显得不能够。那我们可否换个思绪处置惩罚这个题目呢?先思索一个题目:“把大象放入冰箱须要几步”,答案人人都晓得“翻开,装进去,关上”。那一致字符怎样办呢?那就是建立一个足够大的字典
把一切的字符都放进去。
万国码
Unicode 万国码 霹雳一声降生了,望文生义一致了全球的一切笔墨编码能够到 Unicode Consortium 和 codepoints 中检察,对应的完成有UTF8、UTF16
、UTF-32。
可变长度字符编码
UTF8、UTF16、UTF-32最大区分在于对应若干字节的数据,越大能存储的字符也就越多。个中 UTF-8 就是在互联网上运用最广的一种 Unicode 的完成体式格局,也就是如今 html 中最常看到的
所声明字符集。
UTF 最大的特性在于可变长的字节
,比方 UTF8 能够是 1到4个字节来纪录 万国码
,为何这么设想呢?一样平常运用获得的字符对应的字符编码没有必要占用这么多字节,比方 0000 0000
和 0000 0000 0000 0000
都能示意 0,那运用更短的字节所占用的空间更小,传输的速率更快。
小插曲
在一致编码的过程当中还涌现了一个字符集 UCS-2
,它牢固运用 2个字节来编码 与 UTF 可变长度字符编码有肯定程度上的差别,然则跟着一致历程下被 UTF-16
收编了。
Javascript 字符处置惩罚
相识字符基本原理和历程后,那末 Javascript 是什么编码呢?没错它就适才 小插曲
中提到的 UCS-2
,原因是 Javascript 降生时 UTF-16
还没有涌现。
然则如今人人都在运用 UTF 可变长度字符编码
,UTF-16
的可变字节为 2个或许 4个,而 UCS-2
却只有 2个。如许两个字符集之间就有存在一个 UCS-2
没法辨认的 4字节,Javascript 在处置惩罚字符时会傻傻
的按着 UCS-2
的两字节去处置惩罚,再加上字典
里没有这个字符笨笨
的小脑袋瓜没法处置惩罚只能输出乱码。
由于 emoji 脸色的提高,而且 emoji 恰好就是处于 UCS-2
的字典
以外,在前端开辟中碰到能够涌现 emoji 的处所须要小心谨慎:
长度
BUG 预警
如今最为经常使用的 emoji 脸色为 4个字节编码示意,由于 UCS-2
牢固两个字节,在统计长度时 emoji 会被当作两个 UCS-2
字符,效果会和我们预期的输出大了一倍。
let emoji = "😊";
// 输出 2
console.log(emoji.length);
BUG 消除
应用 es6 的 Array.prototype.from
和 spread
来做字符串转数组并计算长度:
let emoji = "😊";
// 输出 1
console.log(Array.from(emoji).length);
// 输出 1
console.log([...emoji].length);
假如不支持 Array.prototype.from
能够应用正则替代把 4字节的字符替代为 _ 并计算长度:
let emoji = "😊";
function countSymbols(string) {
var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
return string
.replace(regexAstralSymbols, '_')
.length;
}
// 输出 1
console.log(countSymbols(emoji));
反转字符串
犹如上面所讲 emoji 会被当作两个 UCS-2
字符,反转的时刻 4个完全的字节会被硬生生的拆分开来,能够运用 Esrever 来处置惩罚。
let emoji = "😊";
// 输出为两个乱码字符
console.log(emoji.split('').reverse().join(''));
字符编码转换
在运用 String.prototype.charCodeAt
和 String.fromCharCode
会涌现题目。能够运用 ES6 的两个新方法来替代 String.prototype.codePointAt
和 String.fromCodePoint
。
正则婚配
正则里 .
示意婚配一个字符,然则 UTF-16
4字节字符会被当作两个字符来处置惩罚,进而引发毛病。ES6 给出了新的处置惩罚方法加上 u
标志 /./u.text('😊')
,所以写正则的时刻要记得加上哦。
字符串遍历
关于字符串的遍历能够运用 for...of
语句。
场景
假如后端数据库运转存储 emoji 作为用户名时,前端在限定用户名长度推断时须要注重UTF-16
4字节字符带来的统计毛病,其他相似场景同理可得。
小提示:在做微信民众号开辟时,由于用户名和用户输入能够涌现 emoji 等字符,须要对数据库举行字符集的设置。
不要问我为何晓得,由于我的眼里常含泪水。
一同生长
在疑心的城市里总少不了并肩偕行的
同伴
让我们一同生长。
- 假如您想让更多人看到文章能够点个
点赞
。 - 假如您想鼓励小二能够到 Github 给个
小星星
。 - 假如您想与小二更多交换增加微信
m353839115
。
本文原稿来自
PushMeTop