Swift中 Character(二)

2021-11-08  本文已影响0人  你duck不必呀

现在的编程语言都支持Unicode字符串,但是处理Unicode字符串又是一个复杂的事情,原因就是Unicode并不是固定宽度的字符

对于ASCII码字符集,每个字符都是固定的宽度1个字节,可以任意存取,但这也仅限于英文字符。在正式开始之前,先要搞清楚Unicode相关的知识

编码点

Unicode字符集,规定了每个字符的编码点(一个16进制数),编码点介于0x0~0x10FFFF之间,但是没有规定计算机怎么存储,具体如何存储编码点就要看编码方式。

编码方式

常见的编码方式有以下几种

UTF-8: 8个位表示一个编码单元,用1-4个编码单元表示一个字符 ,单个字符(ASCII)用一个编码单元就可以表示,所以兼容ASCII码

UTF-16 :要么16个位,要么32位为一个编码单元,大部分的常用字符都用16位编码单元,其余的用32位编码单元

UTF-32 : 32个位表示一个编码单元,最直接的表示法

Swift中UTF-8和UTF-16用UInt8和UInt16表示


Unicode标量

编码单元组成Unicode标量,若要用单个编码单元对应一个Unicode标量,就需要21位编码,也就是UTF-32(向上取整到32位)所以标量是唯一的 21 位数,大部分情况下Unicode标量和编码点是同一个东西

Swift中Unicode标量对应的类型是Unicode.Scalar

字位簇

屏幕上显示的一个字符,可能是单个Unicode标量,也可能由多个Unicode标量的组合(Swift中的字位簇由Character类型表示)


大概了解Unicode相关知识之后,在来看Swift中的Character

Character

Character代表单个可扩展的字位簇,可扩展的字位簇是一个或多个可生成人类可读的字符 Unicode 标量的有序排列

来自文档中的例子:é有两种不同的写法,打印结果都是一样的

let eAcute: Character = "\u{E9}"                         // é
let combinedEAcute: Character = "\u{65}\u{301}"          // e 后面加上  ́
// eAcute 是 é, combinedEAcute 是 é

é可以由单个é,也可以是e 后面跟 ́ 组合成,尽管组合不一样,但是比较结果是相等的,这就是Unicode规范中的标准等价

eAcute == combinedEAcute // true

统计字符个数也是相等,swift能处理

let cafe1 = "Cafe\u{301}" //Café
let cafe2 = "Café"//Café
// count
cafe1.count //4
cafe2.count //4

组成单个字符的Unicode 标量可以是一个或者多个,因此Character类型不能像C语言中char类型的处理方式

let a:Character = "a"
let b:Character = "b"
b - a // Binary operator '-' cannot be applied to two 'Character' operands

一种可行的方案是,asciiValue这里确定强制解包不会有问题

var num = b.asciiValue! - a.asciiValue!

获取Unicode字符的编码

Character的utf8类型是UTF8View,它是扩展的String内部结构体,返回字符的UTF-8编码单元的编码,单个编码单元返回一个UInt8类型的数

let a:Character = "a"
// 单字符的a由 1个utf8编码单元组成
for i in a.utf8{
    print(i) //UInt8: 97
}

// 😊 由 4个 utf8编码单元组成
let face:Character = "😊"
for i in face.utf8{
        print(i)//UInt8: 240 159 152 138
}

类似的,utf16类型是UTF16View,单个编码单元返回一个UInt16类型的数

// 😊 由 2个 utf16编码单元组成
let face:Character = "😊"
for i in face.utf8{
        print(i)//UInt16: 55357 56842
}

unicodeScalars的类型是UnicodeScalarView,返回unicode标量,value返回

let flower = "💐"
for i in flower.unicodeScalars {
    print(i, i.value) // 💐
}

UTF8View,UTF16View,UnicodeScalarView都遵守BidirectionalCollection协议但都不支持随机访问,必须借助Index类型

字符串转数字

字符串转数字,通常用于大数相加,swift中的LONG_LONG_MAX最大值也不过9223372036854775807,对于超出这个范围的值用字符串表示,计算时需要将单个字符串转成数字,相加后在用字符串保存

let bigNumber = "92233720368547758079223372036854775807"

C语言中,通过遍历字符串再和字符0的ASCII码相减就能转换成整数类型,swift中也很方便,bigNumber是由简单字符组成的字符串,通过字符串的utf8属性,就能获取到和ASCII对应的编码

for i in bigNumber.utf8{
    print(i) // 57 50 50 51......53 56 48 55
}
上一篇 下一篇

猜你喜欢

热点阅读