首页 > 代码库 > 5.Swift教程翻译系列——Swift字符串和字符

5.Swift教程翻译系列——Swift字符串和字符

英文版PDF下载地址http://download.csdn.net/detail/tsingheng/7480427

字符串是一组字符的有序序列,比方“hello,china”或者“albatross”。Swfit里字符串用String表示,String也是字符类型Charactar的集合类型。Swift的String和Charactor类型提供了高速的,符合Unicode编码规范的方式来处理文本。

创建或者操作的语法都非常轻便易读。跟C的语法也非常相似。String链接仅仅须要使用简单的加号,定义成变量还是常量决定了其是否能能够改变,这跟其它类型是一样的。

除了简单的语法,Swift的String类型也是一种非常高效,非常现代的一种字符串实现。全部的字符串被解析成Unicode编码字符。并且支持使用Unicode的各种表示方式来获取。

NOTE Swift的String类型是建立在NSString的基础之上的。假设你使用了Cocoa或者CocoaTouch框架,String除了拥有本章将要介绍的一些特性外还支持NSString的全部api接口。你还能够在不论什么须要使用NSString对象的地方使用String值。

1.字符串字面值

你能够使用字符串字面值来定义String。字符串字面值是一个由双引號包围的一个固定文本字符串。

字符串字面值能够用来为常量或者变量提供初始值 let someString = "某个字符串字面值";

注意Swift能够判断出来常量someString是String类型,由于我们使用了字符串字面值来给他初始化。字符串字面值能够包括下面特殊字符:

转义的特殊字符。\0(空字符),\\(反斜杠),\t(制表符),\n(换行符),\r(回车符),\"(双引號)和\‘(单引號)

单字节Unicode标量,写作\xnn,nn是一个两位的十六进制数

两字节Unicode标量。写作\unnnn。nnnn是一个四位的十六进制数

四字节Unicode标量。写作\Unnnnnnnn,nnnnnnnn是一个八位的十六进制数

以下代码对各种特殊字符都举了样例。常量wiseWords包括两个转义的双引號字符。常量dollarSign。blackHeart和sparklingHeart演示了三种不同的Unicode标量格式:

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\x24" // $, Unicode scalar U+0024
let blackHeart = "\u2665" // ?, Unicode scalar U+2665
let sparklingHeart = "\U0001F496" // 特殊字符显示不出来, Unicode scalar U+1F496
2.初始化一个空的字符串

假设想在開始的时候创建一个空的字符串,后面再慢慢加长,一种方式是使用空字符串字面值来初始化。还有一种是调用String的初始化器来初始化。

var emptyString = "" // empty string literal
var anotherEmptyString = String() // initializer syntax
// these two strings are both empty, and are equivalent to each other
你能够通过String的isEmpty属性来查看是否是空字符串:

if emptyString.isEmpty {
    println("Nothing to see here")
}
// prints "Nothing to see here"
3.字符串可变性

你能够通过把字符串对象赋给常量还是变量来决定他能否够被改动。

var variableString = "Horse"
variableString += " and carriage"
// variableString is now "Horse and carriage"

let constantString = "Highlander"
constantString += " and another Highlander"
// this reports a compile-time error - a constant string cannot be modified
NOTE 这个跟OC里面表示字符串能否够被改动的方式不一样,OC里是通过使用NSString和NSMutableString来表示的。

4.字符串是值类型

Swift的字符串是一种值类型。假设你创建了一个字符串,而且当做參数传给函数或者方法的时候是赋值一份传递的,或者赋值给其它常量或者变量都是又一次复制一份的。在这些情况下都会依据原字符串创建一个新的字符串,传递參数或者赋值的时候使用的都是新创建的字符串。

NOTE 这个特性跟Cocoa的NSString不一样。假设在Cocoa里面你创建一个NSString对象,再传递给函数或者方法或者赋值给其它变量,传递或者赋值的都是这个对象的引用,没有创建新的字符串,除非你显示的说须要。

Swift的这个特性能够保证函数或者方法得到传递过来的字符串后自己就拥有那个字符串了,而不用管这个字符串从哪儿来。并且不用操心这个字符串被别人改动,仅仅有我自己能改动。

在这些场景背后,Swift编译器优化了字符串的使用,仅仅有当确实须要复制的时候才会去复制。也就是说你使用值类型的string的时候总能得到非常好的性能。

5.使用字符

Swift的字符串表示了一组字符的有序集合。

各个Character字符值表示了一个单独的Unicode。你能够使用for-in遍历获取字符串中各个单独的字符:

for character in "Dog!表情没办法显示" {
    println(character)
}
// D
// o
// g
// !
// 表情没办法显示
或者还能使用单个字符的字符串字面值来创建一个字符类型常量或变量如 let yenSign: Charactor = "¥"

6.字符计数

假设要查询字符串里面字符的数量,能够调用全局函数countElements而且传递字符串作为參数

let unusualMenagerie = "Koala 表情, Snail <span style="font-family: Arial, Helvetica, sans-serif;">表情</span>, Penguin 表情, Dromedary 表情"
println("unusualMenagerie has \(countElements(unusualMenagerie)) characters")
// prints "unusualMenagerie has 40 characters"
NOTE 对于同一个Unicode字符来说不同的Unicode字符串和不同的表现形式须要的内存大小是不一样的。

所以字符串中各个字符所占用的内存是不一样的。所以字符串长度就不能不按顺序遍历各个字符来计算了。假设你使用了特别长的字符串,注意countElements函数会按顺序遍历字符串中的字符来计算字符数量。

还要注意countElements函数返回的结果跟相应的NSString的length属性并不总是相等的。NSString的length属性是基于UTF-16形式的字符串中16位单元的个数。而不是字符串中Unicode字符的数量。

Swift的String类型跟NSString的length相应的是utf16count属性。

7.连接字符串和字符

字符串和字符能够使用加号连接组成一个新的字符串

let string1 = "hello"
let string2 = " there"
let character1: Character = "!"
let character2: Character = "?

" let stringPlusCharacter = string1 + character1 // equals "hello!" let stringPlusString = string1 + string2 // equals "hello there" let characterPlusString = character1 + string1 // equals "!hello" let characterPlusCharacter = character1 + character2 // equals "!?

"

你还能够使用+=运算符将字符串或字符追加到一个已有的字符串变量后面

var instruction = "look over"
instruction += string2
// instruction now equals "look over there"

var welcome = "good morning"
welcome += character1
// welcome now equals "good morning!"
NOTE 不能把字符串或字符追加到字符后面哦,由于字符类型仅仅能包括单个字符。

8.字符串填补

字符串填补能够通过在一个字符串字面值中增加混合的常量变量。字面量和表达式来创建新的字符串值。每一个增加字符串字面值的对象都要加上一对括号和反斜杠前缀:

let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
上面资历中multiplier的值被已\(multiplier)的形式插入到字符串字面值其中。当字符串填补计算过以后这个地方将会用multiplier的实际值来取代以创建一个实际的字符串。

在字符串的后面multiplier还是一个表达式的一部分。这个表达式计算Double(multiplier)*2.5的值而且插入结果7.5到字符串中。

这里表达式被写作\(Double(multiplier)*2.5)增加字符串字面值中。

NOTE 通过使用这样的方式填补进字符串常量的表达式不能包括未经转义的双引號或者反斜杠,也不能包括回车或者换行。

9.字符串比較

Swift提供三种字符串比較方式:相等,前缀相等和后缀相等

相等

假设两个字符串包括同样的字符而且排序也同样,就被觉得是相等的。

let quotation = "We‘re a lot alike, you and I."
let sameQuotation = "We‘re a lot alike, you and I."
if quotation == sameQuotation {
    println("These two strings are considered equal")
}
// prints "These two strings are considered equal"
前缀相等和后缀相等

假设要检查字符串是否有特殊的前缀和后缀,调用字符串的hasPrefix和hasSuffix方法,两个方法都有一个字符串类型參数。返回布尔值。

两个方法都对原字符串与前缀字符串或后缀字符串进行一个一个字符的比对。效果应该是和JAVA的startWith和endWidth一样吧。

以下的样例把前两幕罗密欧与朱丽叶的地点作为一个数组:

let romeoAndJuliet = [
    "Act 1 Scene 1: Verona, A public place",
    "Act 1 Scene 2: Capulet‘s mansion",
    "Act 1 Scene 3: A room in Capulet‘s mansion",
    "Act 1 Scene 4: A street outside Capulet‘s mansion",
    "Act 1 Scene 5: The Great Hall in Capulet‘s mansion",
    "Act 2 Scene 1: Outside Capulet‘s mansion",
    "Act 2 Scene 2: Capulet‘s orchard",
    "Act 2 Scene 3: Outside Friar Lawrence‘s cell",
    "Act 2 Scene 4: A street in Verona",
    "Act 2 Scene 5: Capulet‘s mansion",
    "Act 2 Scene 6: Friar Lawrence‘s cell"
]
你能够对remeoAndJuliet数组使用hasPrefix方法来计算第一幕有几场

var act1SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 1 ") {
        ++act1SceneCount
    }
}
println("There are \(act1SceneCount) scenes in Act 1")
// prints "There are 5 scenes in Act 1"
相同的道理能够使用hasSuffix来计算有几场在Capulets mansion和Lawrence‘s cell附近拍摄

var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
    if scene.hasSuffix("Capulet‘s mansion") {
        ++mansionCount
    } else if scene.hasSuffix("Friar Lawrence‘s cell") {
       ++cellCount
    }
}
println("\(mansionCount) mansion scenes; \(cellCount) cell scenes")
// prints "6 mansion scenes; 2 cell scenes"
10.字符串字母大写和小写转换

你能够通过字符串的uppercaseString和lowercaseString属性来获得对应的大写或者小写版本号:

let normal = "Could you help me, please?"
let shouty = normal.uppercaseString
// shouty is equal to "COULD YOU HELP ME, PLEASE?"
let whispered = normal.lowercaseString
// whispered is equal to "could you help me, please?

"

11.Unicode

Unicode是一种编码和表示文本的国际标准。他能够让你使用一种标准的形式表示不论什么语言的不论什么字符。从外部资源比如文本文件或者web页面读或者写这些字符。

Swift的字符串和字符类型都是全然兼容Unicode标准的。

他们支持几种不同的Unicode编码。

Unicode术语

在Unicode中每个字符能够被表示未一个或多个unicode标量。一个Unicode标量是一个相应字符或表情的唯一的21位数字,比方U+0016相应小写拉丁字母a。或者U+1F425代表表情符号xxx。

当一个Unicode字符串被写入文本文件或者其它方式存储的时候,这些unicode标量被一种Unicode格式编码。

每种格式将字符串编码成块,也就是代码单元。这些格式包含UTF-8格式(使用8位代码单元编码字符串),UTF-16格式(使用16位代码单元编码字符串)。

字符串的Unicode表示法

Swift提供了几种不同的方式来使用字符串的Unicode表示法。

你能够使用for-in语句遍历字符串的各个字符作为Unicode字符。

或者。能够通过下面三种之中的一个的其它Unicode兼容表示法来获取字符串。

UTF-8代码单元集合(通过字符串的utf8属性)

UTF-16代码单元集合(通过字符串的utf16属性)

21位Unicode标量值集合(通过字符串的unicodeScalars属性)

以下样例列举了各种不同的表示法,字符串由字符D,o,g,!,和表情狗狗字符(这里显示不了。Unicode标量U+1f436)

let dogString = "Dog!狗狗";

UTF-8

你能够通过遍历字符串的utf8属性来获取UFT-8表示法。这个属性返回的是UTF8View类型。是UInt8值的集合。

字符串里面各个字节表演示样例如以下:

for codeUnit in dogString.utf8 {
    print("\(codeUnit) ")
}
print("\n")
// 68 111 103 33 240 159 144 182
上面样例前四个数字codeUnit值是68,111,103,33表示了字符D。o。g,和!,这些字符的UTF-8表示与ASCII表示是一样的。

最后四个codeUnit值是240,159,144,182是狗狗表情字符的四字节的表示。
UTF16

你能够通过遍历字符串的utf16属性来获取UTF16表示法。这个属性返回的是UTF16View类型,是UInt16值的集合。字符串里面各个字节表演示样例如以下:

for codeUnit in dogString.utf16 {
    print("\(codeUnit) ")
}
print("\n")
// 68 111 103 33 55357 56374
前四个数字还是一样的。68,111,103,33。表示了字符D,o,g,!。这些字符的UTF-16代码单元和UTF-8表示法是一样的。

最后两个值是55357和56374是狗狗表情字符的UTF-16表示。分别代表了值U+D83D和U+DC36。

Unicode标量

你能够通过遍历字符串的unicodeScalars属性来获取Unicode标量表示。

这个属性返回的结果是UnicodeScalarView类型,是UnicodeScalar值的集合。UnicodeScalar是不论什么21位非前替换或者后替换的代码。

各个UnicodeScalar有一个能够返回自己21位置的属性value。结果使用UInt32值来表示。


for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ")
}
print("\n")
// 68 111 103 33 128054
前四个value属性设置都还是68,111,103,33。最后一个128054是十六进制数1F436。正好就是狗狗表情字符的Unicode标量U+1F436。

还有第二种能够获取UnicodeScalar的value属性的方式,就是使用这个字符来创建新的字符串值,比方字符串填补:

for scalar in dogString.unicodeScalars {
    println("\(scalar) ")
}
// D
// o
// g
// !
// 狗狗表情

本章完。下章地址: 6.集合属性








5.Swift教程翻译系列——Swift字符串和字符