Swift中String和Character的使用與總結

My Den發表於2016-03-09

使用String字面量給常量賦值

let string = "string literal value"

常量string將會自動推斷為String型別

初始化一個空的String

var emptyStr = ""              //使用空字串字面量  
var anotherEmptyStr = String() //使用構造方法  
//兩者沒有區別

使用isEmpty判斷空String:

if emptyStr.isEmpty {  
    print("have nothing here")
}

String的可變性

使用“+”連線字串,當然也支援自加運算子”+=”

var variableStr = "LastName"  
variableStr += "and FirstName"  
/// variableStr is "LastName and FirstName"

//**but if:
let constantStr = "Gender"  
constantStr += "and another Highlander"  
///編譯器會報錯,被宣告為常量的字串不能被修改!

跟oc不同,swift的String通過var/let 變數/常量 標識決定其是否可變(can be mutated),而不需要選擇NSString 還是 NSMutableString。

String是值型別

區別引用型別,在String在方法間傳遞,或者將其賦值給一個常量或者變數時,該String將會被複制(copy),而不是指向原來的物件。

String跟Characters的連線

let str = "hello world "  
let char: Character = "!"  
str.append(char)  
// 結果str為: "hello world !"

遍歷String

for char in "myStr".characters {  
    print(char)
}
//m
//y
//S
//t
//r

字串插值

在字串中插入常量變數表示式等,構造一個新的字串”通過()”:

let multiplier = 3  
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"  
/// message is "3 times 2.5 is 7.5"

String中使用轉義字元

在字串中輸入反斜線”\” 水平製表符”t” 換行”n” 雙引號”“” 單引號”’” 等都需要在前面新增”\”進行轉義,同時可以在轉義字元後新增Unicode來進行特殊符號表情的顯示:

//**雙引號轉義
let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"  
///"Imagination is more important than knowledge" - Einstein

//**Unicode轉義
let dollarSign = "\u{24}"        
let blackHeart = "\u{2665}"      
let sparklingHeart = "\u{1F496}" 

//**擴充套件自行集
//**對應關係
//  \u{D55C}----한
//  \u{1112}----ᄒ
//  \u{1161}----ᅡ
//  \u{11AB}----ᆫ
let KoreaStr = "\u{D55C}\u{1112}\u{1161}\u{11AB}"

String長度

string.characters.count

let str = "1234567890"  
print("str has \(str.characters.count) characters")  
//輸出 "star has 10 characters"

//**為String增加筆畫不會造成長度增加:
var str = "cafe"  
print("the number of characters in \(word) is \(word.characters.count)")  
// 輸出 "the number of characters in cafe is 4"
//**now append some Unicode:
word += "\u{301}"  
print("the number of characters in \(word) is \(word.characters.count)")  
//輸出 "the number of characters in café is 4"
//僅僅是改變了最後一個字元,並沒有增加字串的長度

正因為swift支援擴充套件字形集,不同的字元,和相同的不同表示的字元可能需要不同量的儲存器來儲存,所以在swift中characters所佔用的儲存量是不一定相同的,因此不能像oc計算NSString那樣使用字串來迭代計算,而應該遍歷字串的characters來確定字串的長度。

訪問和修改字串

可以通過其方法和屬性,或者下標,來訪問或者修改字串

字串索引

swift中的字串具有相關連的索引型別(String.Index),可對應其每個位置的Character

正如上面所說,不同的字串可能需要不同數量的記憶體來儲存,所以為了確定哪些character在特定的位置上,我們必須遍歷確定每個Unicode的開始結束位置,因此,String不能使用整形作索引。

startIndex: 訪問String第一個位置的字元 endIndex: 訪問String最後一個位置的字元
(一個空的字串或者長度為1的字串,startIndex和endIndex相等)

predecessor(), successor(), advancedBy() 一個String.Index值可以通過呼叫predecessor()方法來訪問其前一個index, 呼叫successor()來訪問其後一個index, 或者呼叫advancedBy()來指定訪問相對位置的index( 之後5位的index: advancedBy(5) 往前5位的index: advancedBy(-5) )

let greeting = "Guten Tag!"  
greeting[greeting.startIndex]  
//G
greeting[greeting.endIndex.predecessor()]  
//!
greeting[greeting.startIndex.successor()]  
//u
let index = greeting.startIndex.advancedBy(7)  
//a
greeting[index]  
//輸出 a

indiced : 字串Index的集合

for index in greeting.characters.indices {  
    print("\(greeting[index])", terminator: " ")
}
///prints "G u t e n  T a g !"

插入/移除

利用index,在制定位置插入字元character

var helloStr = "hello"  
helloStr.insert("~", atIndex: helloStr.endIndex)  
// hello~

同理,插入字串(字元的集合)

var helloStr = "hello!"  
helloStr.insertContentOf(" world!".characters, at: hello.endIndex)  
// hello! world

//用上面的知識,再追求下完美:
var helloStr = "hello!"  
helloStr.insertContentOf(" world".characters, at: hello.endIndex.predecessor())  
// hello world!

移除(index):

var helloStr = "hello world!"  
helloStr.removeAtIndex(helloStr.endIndex.predecessor())  
// hello world
//注意:
// endIndex是指最後一個index位(將要輸入內容的index位)
//所以刪除最後一個字元使用的index是endIndex.predecessor()(將要輸入內容的index的前一個index位)
//而不是endIndex

移除(Range):

var helloStr = "hello world!"  
let range = Range(start: helloStr.endIndex.advancedBy(-6), end: helloStr.endIndex.predecessor())  
// 順便貼一個new Range的簡易寫法:
// let range = helloStr.endIndex.advancedBy(-6)..<helloStr.endIndex
// 效果是一樣的
helloStr.removeRange(range)  
// hello

字串比較

兩個純字串比較

let oneStr = "We're a lot alike, you and I."  
let anotherStr = "We're a lot alike, you and I."

if oneStr == anotherStr {  
    print("These two strings are considered equal")
}
//輸出: These two strings are considered equal
//相等

兩個由characters組成的字串比較

let oneStr = "Voulez-vous un caf\u{E9}?"  
//Voulez-vous un café?
let anotherStr = "Voulez-vous un caf\u{65}\u{301}?"  
//Voulez-vous un café?
//兩者雖然看起來內容字元不同,其實\u{65}\u{301}是一個e和一個音調符號,根據上面的知識,結果組合成é(\u{E9})

if oneStr == anotherStr {  
    print("These two strings are considered equal")
}
//輸出: These two strings are considered equal
//相等

兩個表現相同的character比較

let oneChar: Character = "\u{41}"  
//拉丁字母中的A
let anotherChar: Character = "\u{0410}"  
//西裡爾字母中的A

if oneChar != anotherChar {  
    print(These two characters are not equivalent)
}
//輸出: These two characters are not equivalent
//不相等!

字首和字尾的比較 我們可以使用hasPrefix()方法和hasSuffix()去匹配String的字首和字尾,並返回一個Boolean值

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"
]
//----遍歷這個字元陣列,匹配下字首看看效果
var count = 0  
for str in romeoAndJuliet {  
    if str.hasPrefix("Act 1 ") {
        count++
    }
}
print("There are \(count) string with Act 1 ")  
// 輸出: "There are 5 string with Act 1"

//----字尾呢
var count = 0  
for str in romeoAndJuliet {  
    if str.hasSuffix("Capulet's mansion") {
        count++
    } 
}
print("There are \(count) mansion string")  
// 輸出: "There are 6 mansion stressing"

String使用UTF-8編碼表示

複習一下,上面也提到,Swift中的String支援emoji表情和眾多特殊字元,這也是String一個單位長度不一定等於兩個character(漢字)或者1個character(英文字母)的原因。 先回到我們的話題。String和UTF-8的對應關係,我們來看一張官方電子書中的表: ![]/content/images/2015/12/utf8.png()

//上圖中對應的String:
//let dogString = "Dog!!"

//同時String中的UTF-8編碼也是可以像char那樣遍歷的
for unitCode in dogString.utf8 {  
    print("\(unitCode) ", terminator: "")
}
//輸出: 68 111 103 226 128 188 240 159 144 182

同理String也可以以UTF-16 和Unicode的方式遍歷

for unitCode in dogString.utf16 {  
}

for scalar in dogString.unicodeScalars {  
    print("\(scalar.value) ", terminator: "")
}
// 68 111 103 8252 128054

for scalar in dogString.unicodeScalars {  
    print("\(scalar) ", terminator: "")
}
// D o g !! 

//注意: 直接printunicodeScalar的話跟String的輸出是一樣效果的
//我們print出他的value,才是我們想要的編碼

相關文章