- 1 .字符串字面量
String
在Swift中字符串字面量是由雙引號
" "
包裹著的
let someString = "Some string literal value"
像我們在 Swift 3 學(xué)習(xí) 01 中講述的那樣良拼,Swift 會推斷該常量為String類型
- 2 .初始化空字符串
- 2.1 初始化
創(chuàng)建一個空字符串的兩種方式
//(1)可以將空的字符串字面量賦值給變量
var emptyString = "" // empty string literal
//(2)初始化一個新的String實例
var anotherEmptyString = String() // initializer syntax
// these two strings are both empty, and are equivalent to each other
- 2.2 判斷空字符串
用
isEmpty
屬性來判斷該字符串是否為空,返回值為Bool
var emptyString = ""
if emptyString.isEmpty {
print("Nothing to see here")
}
// Prints "Nothing to see here"
- 3 .字符串可變性
在 Objective-C 中坤学,需要通過選擇兩個不同的類(NSString和NSMutableString)來指定字符串是否可以被修改米间。而在Swift中用
let
聲明常量來保證其不會被修改统求,用var
聲明變量來對其進行修改痹兜。
//可變的字符串
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
- 4 .字符串是值類型
Swift 的
String
類型是值類型再登。 如果創(chuàng)建了一個新的字符串方篮,那么當(dāng)其進行常量有缆、變量賦值操作象踊,或在函數(shù)/方法中傳遞時,會進行值拷貝棚壁。
這樣做的好處是杯矩,你可以確信傳遞的字符串不會被修改,除非你自己去修改它袖外。
在 Objective-C 中,你可能面臨著值被 '別人' 修改的風(fēng)險史隆,比如下面的a
.你并沒有去直接修改ta.
NSString * a;
NSMutableString * b = [@"111111" mutableCopy];
a = b;
[b appendString:@"222222"];
NSLog(@"a = %@",a); //a = 111111222222
在Swift中,無論怎樣都不會將你的 a
修改 在刺,除非你直接對 a
進行修改逆害。
var a : String;
var b = "111111"
a = b;
b = b.appending("222222");
print("a = \\(a)\\n") //輸出的 a = 111111
- 5 . 使用字符
Character
- 5.1 獲取字符串的字符
通過
for-in
循環(huán)來遍歷字符串中的characters
屬性來獲取每一個字符的值.
for character in "Dog!".characters {
print(character)
}
// D
// o
// g
// !
//
- 5.2 聲明一個字符
通過
Character
關(guān)鍵字聲明一個字符
let exclamationMark2: Character = "!"
必須要用Character
聲明才能得到一個字符,否則會被Swift推斷為String
類型蚣驼。
- 5.3 用字符數(shù)組初始化一個字符串
字符串可以通過傳遞一個值類型為
Character
的數(shù)組作為自變量來初始化魄幕。
let catCharacters: [Character] = ["C", "a", "t", "!", ""]
let catString = String(catCharacters)
print(catString)
// Prints "Cat!"
- 6 .連接字符串和字符
+
、+=
颖杏、append()
你可以不追加
String
或Character
到現(xiàn)有的Character
變量纯陨,因為一個Character
值必須只包含一個字符。
- 6.1
+
- 6.1
字符串可以通過加法運算符(+)相加在一起(或稱“連接”)創(chuàng)建一個新的字符串,在前面的文章提及過留储。
let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome now equals "hello there"
- 6.2
+=
- 6.2
可以通過加法賦值運算符 (+=) 將一個字符串添加到一個已經(jīng)存在字符串變量上
var instruction = "look over"
instruction += string2
// instruction now equals "look over there
- 6.3
append()
- 6.3
可以用append()方法將一個字符附加到一個字符串變量的尾部
let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome now equals "hello there!"
- 7 .字符串插值
\\(a)
Swift提供便利的方式在字符串中插入一些值翼抠。
a
可以是常量、變量获讳、字面量和表達式阴颖。 插入的字符串字面量的每一項都在以反斜線為前綴的圓括號中 即\\(a)
let multiplier = 3
let message = "\\(multiplier) times 2.5 is \\(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
在上述代碼中 \\(multiplier)
做為整體插入到字符串中,在系統(tǒng)讀取時會將對應(yīng)的值插入該位置丐膝。
- 8 .Unicode
Unicode 是一個國際標準量愧,用于文本的編碼和表示钾菊。Swift 的String和Character類型是完全兼容 Unicode 標準的。
- 8.1 Unicode 標量
Swift 的String類型是基于 Unicode 標量 建立的偎肃。 Unicode 標量是對應(yīng)字符或者修飾符的唯一的21位數(shù)字煞烫,例如
U+0061
表示小寫的拉丁字母("a"),U+1F425
表示小雞表情("")累颂。
Unicode 碼位的范圍是U+0000
到U+D7FF
或者U+E000
到U+10FFFF
滞详。Unicode 標量不包括 Unicode 代理項(surrogate pair) 碼位,其碼位范圍是U+D800
到U+DFFF
紊馏。
- 8.2 字符串字面量的特殊字符
字符串字面量可以包含以下特殊字符:
轉(zhuǎn)義字符\\0
(空字符)料饥、\\\\\\\\
(反斜線)、\\t
(水平制表符)瘦棋、\\n
(換行符)稀火、\\r
(回車符)、\\"
(雙引號)赌朋、\\'
(單引號)凰狞。
Unicode 標量,寫成\\u{n}
(u為小寫)沛慢,其中n為任意一到八位十六進制數(shù)且可用的 Unicode 位碼赡若。
- 8.2 字符串字面量的特殊字符
let wiseWords = "\\"Imagination is more important than knowledge\\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\\u{24}" // $, Unicode scalar U+0024
let blackHeart = "\\u{2665}" // , Unicode scalar U+2665
let sparklingHeart = "\\u{1F496}" // , Unicode scalar U+1F496
- 9 .計算字符數(shù)量
count
使用字符串的
characters
屬性的count
屬性獲取字符數(shù)量。
let unusualMenagerie = "Koala , Snail , Penguin , Dromedary " //只占一個字符团甲。
print("unusualMenagerie has \\(unusualMenagerie.characters.count) characters")
// Prints "unusualMenagerie has 40 characters"
- 10 .可擴展的字形群集
每一個 Swift 的
Character
類型代表一個可擴展的字形群逾冬。 一個可擴展的字形群是一個或多個可生成人類可讀的字符 Unicode 標量的有序排列。
舉個例子躺苦,字母é
可以用單一的 Unicode 標量é(LATIN SMALL LETTER E WITH ACUTE, 或者U+00E9)來表示身腻。
然而一個標準的字母e
(LATIN SMALL LETTER E或者U+0065) 加上一個急促重音(COMBINING ACTUE ACCENT)的標量(U+0301),這樣一對標量就表示了同樣的字母é
匹厘。 這個急促重音的標量形象的將e
轉(zhuǎn)換成了é
嘀趟。
簡單而言e (U+0065)
+U+0301
-->é(U+00E9)
,eAcute
和combinedEAcute
等價
let eAcute: Character = "\\u{E9}" // é
let combinedEAcute: Character = "\\u{65}\\u{301}" // e followed by ?
// eAcute is é, combinedEAcute is é
再比如在韓文中愈诚,下面的precomposed
和decomposed
等價
let precomposed: Character = "\\u{D55C}" // ?
let decomposed: Character = "\\u{1112}\\u{1161}\\u{11AB}" // ?, ?, ?
// precomposed is ?, decomposed is ?
再比如地域性指示符號的 Unicode 標量可以組合成一個單一的Character值
let regionalIndicatorForUS: Character = "\\u{1F1FA}\\u{1F1F8}"
// regionalIndicatorForUS is
- 11 .計算字符數(shù)量
count
通過characters屬性
count
屬性獲取字符數(shù)量她按, Swift 中的字符在一個字符串中并不一定占用相同的內(nèi)存空間數(shù)量。另外需要注意的是通過characters屬性返回的字符數(shù)量并不總是與包含相同字符的NSString的length
屬性相同炕柔。NSString的length
屬性是利用 UTF-16 表示的十六位代碼單元數(shù)字酌泰,而不是 Unicode 可擴展的字符群集。當(dāng)一個Swift的String值 被NSString的length
屬性訪問時匕累,字符數(shù)量和字符串長度是不一樣的陵刹。
let unusualMenagerie = "Koala , Snail , Penguin , Dromedary "
print("unusualMenagerie has \\(unusualMenagerie.characters.count) characters")
// Prints "unusualMenagerie has 40 characters"
//下面的代碼作為字符串算長度
var str : NSString;
str = unusualMenagerie as NSString ;
print("str.length = \\(str.length)"); //str.length = 44
- 12 . 字符串索引
每一個String值都有一個關(guān)聯(lián)的索引(index)類型,String.Index欢嘿,它對應(yīng)著字符串中的每一個Character的位置衰琐。
前面提到巡验,不同的字符可能會占用不同數(shù)量的內(nèi)存空間,所以要知道Character的確定位置碘耳,就必須從String開頭遍歷每一個 Unicode 標量直到結(jié)尾。因為整數(shù)(integer)是內(nèi)存空間的概念框弛,不同的字符可能會占用不同數(shù)量的內(nèi)存空間辛辨,Swift 的字符串不能用整數(shù)(integer)做索引。
使用startIndex
屬性可以獲取一個String的第一個Character的索引瑟枫。使用endIndex
屬性可以獲取最后一個Character的后一個位置的索引斗搞。因此,endIndex
屬性不能作為一個字符串的有效下標慷妙。如果String是空串僻焚,startIndex
和endIndex
是相等的。
通過調(diào)用 String 的index(before:)
或index(after:)
方法膝擂,可以立即得到前面或后面的一個索引虑啤。您還可以通過調(diào)用index(_:offsetBy:)
方法來獲取對應(yīng)偏移量的索引,這種方式可以避免多次調(diào)用index(before:)
或index(after:)
方法架馋。
let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a
試圖獲取越界索引對應(yīng)的 Character狞山,將引發(fā)一個運行時錯誤
fatal error: Can't form a Character from an empty String
greeting[greeting.endIndex] // error
greeting.index(after: endIndex) // error
使用 characters 屬性的 indices
屬性會創(chuàng)建一個包含全部索引的范圍(Range),用來在一個字符串中訪問單個字符叉寂。
for index in greeting.characters.indices {
print("\\(greeting[index]) ", terminator: "")
}
// Prints "G u t e n T a g ! "
- 13 .插入
調(diào)用
insert(_:atIndex:)
方法可以在一個字符串的指定索引插入一個字符萍启,調(diào)用insert(contentsOf:at:)
方法可以在一個字符串的指定索引插入一段字符串。(用在遵循Collection協(xié)議的類型)
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
welcome.insert(contentsOf:" there".characters, at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"
- 14 .刪除
調(diào)用 remove(at:) 方法可以在一個字符串的指定索引刪除一個字符屏鳍,調(diào)用 removeSubrange(_:) 方法可以在一個字符串的指定索引刪除一個子字符串勘纯。(用在遵循RangeReplaceableCollection協(xié)議的類型)
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
- 15 .比較字符串
Swift 提供了三種方式來比較文本值:字符串字符相等、前綴相等和后綴相等
- 15.1 字符串/字符相等
字符串/字符可以用等于操作符(==)和不等于操作符(!=)
let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
print("These two strings are considered equal")
}
// Prints "These two strings are considered equal"
如果兩個字符串(或者兩個字符)的可擴展的字形群集是標準相等的钓瞭,那就認為它們是相等的驳遵。在這個情況下,即使可擴展的字形群集是有不同的 Unicode 標量構(gòu)成的降淮,只要它們有同樣的語言意義和外觀超埋,就認為它們標準相等。
像上面提到的 e (U+0065)
+ U+0301
--> é(U+00E9)
這兩個字符群集都是表示字符é的有效方式佳鳖,所以它們被認為是標準相等霍殴。
// "Voulez-vous un café?" using LATIN SMALL LETTER E WITH ACUTE
let eAcuteQuestion = "Voulez-vous un caf\\u{E9}?"
// "Voulez-vous un café?" using LATIN SMALL LETTER E and COMBINING ACUTE ACCENT
let combinedEAcuteQuestion = "Voulez-vous un caf\\u{65}\\u{301}?"
if eAcuteQuestion == combinedEAcuteQuestion {
print("These two strings are considered equal")
}
// Prints "These two strings are considered equal"
相反,英語中的LATIN CAPITAL LETTER A(U+0041系吩,或者A)不等于俄語中的CYRILLIC CAPITAL LETTER A(U+0410来庭,或者A)。兩個字符看著是一樣的穿挨,但卻有不同的語言意義:
let latinCapitalLetterA: Character = "\\u{41}"
let cyrillicCapitalLetterA: Character = "\\u{0410}"
if latinCapitalLetterA != cyrillicCapitalLetterA {
print("These two characters are not equivalent.")
}
// Prints "These two characters are not equivalent."
- 15.2 前綴/后綴相等
通過調(diào)用字符串的
hasPrefix(_:)
/hasSuffix(_:)
方法來檢查字符串是否擁有特定前綴/后綴月弛,兩個方法均接收一個String類型的參數(shù)肴盏,并返回一個布爾值。
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"
]
前綴 hasPrefix(_:)
,如下統(tǒng)計由Act 1
開頭的字符串
var act1SceneCount = 0
for scene in romeoAndJuliet {
if scene.hasPrefix("Act 1 ") {
act1SceneCount += 1
}
}
print("There are \\(act1SceneCount) scenes in Act 1")
// Prints "There are 5 scenes in Act 1"
后綴 hasSuffix(_:)
,如下統(tǒng)計由Capulet's mansion
結(jié)尾的字符串
var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
if scene.hasSuffix("Capulet's mansion") {
mansionCount += 1
} else if scene.hasSuffix("Friar Lawrence's cell") {
cellCount += 1
}
}
print("\\(mansionCount) mansion scenes; \\(cellCount) cell scenes")
// Prints "6 mansion scenes; 2 cell scenes"
- 16 .字符串的 Unicode 表示形式
UTF-8 : 通過遍歷String的utf8屬性來訪問它的UTF-8表示
UTF-16 : 通過遍歷String的utf16屬性來訪問它的UTF-16表示
UTF-32: 遍歷String值的unicodeScalars屬性來訪問它的 Unicode 標量表示
let dogString = "Dog"
//UTF-8
for codeUnit in dogString.utf8 {
print("\\(codeUnit) ", terminator: "")
}
print("")
//UTF-16
for codeUnit in dogString.utf16 {
print("\\(codeUnit) ", terminator: "")
}
print("")
//UTF-32
for scalar in dogString.unicodeScalars {
print("\\(scalar.value) ", terminator: "")
}
print("")
Character | UTF-8 Code Unit | UTF-16 Code Unit |UTF-32 Code Unit |Position
----|------|----|----|----|---
D(U+0044) | 68|68|68|0
o(U+006F )| 111|111|111|1
g(U+0067)| 103|103|103|2
還是直接上圖吧帽衙,官方圖哈哈
以上只是一些簡單的概念說(fan)明(yi)菜皂,如有錯誤請指正,謝謝厉萝。Swift 3 學(xué)習(xí) 恍飘,后續(xù)會不斷更新。
如果你覺得我的文章對你有幫助請點喜歡哦谴垫,也可以關(guān)注我章母,每周至少一篇技術(shù)更新。
或者關(guān)注 我的專題 每周至少5篇高質(zhì)量文章收錄翩剪,多謝支持乳怎。
一起學(xué)習(xí),一起進步