首页 > 代码库 > 5.Swift字符串和字符

5.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

未完待续。。。