Unicode

作者: 小金_1180 | 来源:发表于2018-06-20 17:52 被阅读0次

        Unicode是一套国际通用的编码标准,用于在不同的系统中表示和处理文本数据。它让你可以用同一种形式表示几乎所有国家的所有语言,并且可对外部数据源进行读写操作,比如文本文件或者web页面。

        Swift的String和Character类型是完全兼容Unicode的,之前文章中也提过。

    Unicode标量

        本质上,Swift中的String类型是通过Unicode标量创建的。一个Unicode标量是一个独一无二的21位的数字,代表了一个字符或者修饰符。比如U+0061表示了LATIN SMALL LETTER A的a,U+1F425表示FRONT-FACING BABY CHICK🐥。

        需要注意的是不是所有的21位的Unicode编码单元都被分配给了一个字符,有一些是保留到未来分配的。已经被分配给字符使用的标量一般都有一个名字,比如上述例子中的LATIN SMALL LETTER AFRONT-FACING BABY CHICK。

    NOTE:一个Unicode标量是一个编码空间在[U+0000,U+D7FF] 或者[U+E000 ,U+10FFFF]中的任意编码单元。Unicode不包含代理对,也就是处于编码空间[U+D800, U+DFFF]中的编码单元。

    可扩展的字形集群

        Swift中的每一个Character实例都表示了一个单独的可扩展的字形集群。一个可扩展的字形集群由一个或者多个Unicode标量组成,并可以生成人类可读的字符。

            let eAcute: Character = "\u{E9}" // é

            let combinedEAcute: Character = "\u{65}\u{301}"          // e followed by ́

            // eAcute is é, combinedEAcute is é

        上面是一个例子,字母é可以用单独的Unicode标量表示(LATIN SMALL LETTER E WITH ACUTE, or U+00E9),然而,字母é也可以用一对标量表示出来-----字母e(LATIN SMALL LETTER)后面跟随一个字母  ́(COMBINING ACUTE ACCENT) ,也就是U+0065跟随U+0301。在标量COMBINING ACUTE ACCENT被Unicode文本渲染系统渲染的时候,他会以图形化的方式作用于它前面的标量。把e变成é。

        上面的两个例子中,字母é都是用一个单独的Character值来表示出字形集群。第一个例子,集群包含了一个标量,第二个例子,包含了2个标量。

        可扩展的字符集群增加了灵活性,是我们可以使用一个单独的字符去表示很多复杂的脚本字符。比如,韩国字母中的音节可以表示成一组被预分解或者分解后的元素。下面两个字符在Swift中表示同一个字形:

            let precomposed: Character = "\u{D55C}" // 한

            let decomposed: Character = "\u{1112}\u{1161}\u{11AB}"  // ᄒ, ᅡ, ᆫ

            // precomposed is 한, decomposed is 한

        可扩展的字符集群使可以包围其他的标量,使其称为字符的一部分:

            let enclosedEAcute: Character = "\u{E9}\u{20DD}"

            // enclosedEAcute is é⃝     

    地区指示符的Unicode标量可以被组合在一起,生成一个新的字符,比如把REGIONAL INDICATOR SYMBOL LETTER U (U+1F1FA)和 REGIONAL INDICATOR SYMBOL LETTER S (U+1F1F8)组合在一起:

            let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"

            // regionalIndicatorForUS is 🇺🇸

    字符的数量

    要获取String中character的数量,可以使用String的count属性:

            let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"

            print("unusualMenagerie has \(unusualMenagerie.count) characters")

            // 打印 "unusualMenagerie has 40 characters

    值得注意的是,由于Swift中Character对可扩展自信集群的使用,使得字符串的连接或修改并不一定会改变字符串中字符的数量。

            var word = "cafe"

            print("the number of characters in \(word) is \(word.count)")

            // "the number of characters in cafe is 4"

            word += "\u{301}"    // COMBINING ACUTE ACCENT, U+0301

            print("the number of characters in \(word) is \(word.count)")

            // "the number of characters in café is 4

        例如,你先使用4个字符cafe初始化了一个新的字符串,然后在末尾拼接上字符COMBINING ACUTE ACCENT (U+0301),结果还是4个字符,因为第4个字符从e变成了é

    NOTE:可扩展的字形群可以有多个Unicode标量组成,这就意味着不同的字符或者字符相同代表的结果却不同,需要存储的内存也不一样。因此,Swift中,字符串中的字符所占的内存不都是一样的。这就导致了如果不遍历字符串就无法确定字形群的边界,也就无法确定字符串中字符的数量。如果你正在处理特别长的字符串,注意count属性需要遍历整个字符串的Unicode标量以确定字符串的字符数量。

    拥有相同字符的NSString的length和count返回的字符的数量不总是相同的。NSString的length是基于Utf-16的,也就是16位的代码单元,而不是String中可扩展字形群。

    相关文章

      网友评论

          本文标题:Unicode

          本文链接:https://www.haomeiwen.com/subject/aykxyftx.html