Swift4.0學習之路第7講 字符與字符串

文檔GitHub地址

一、字符概述

Swift編程語言中,對字符的表示是獨立于某一種特定的Unicode編碼的。在Objective-CJava等編程語言中,編譯器內部一般以UTF-16編碼格式保存并處理字符序列的,而在Swift編程語言中則是直接通過Unicode標準組織所制定的標準碼點(code point)來保存并處理字符串字符序列的。在Swift中把Unicode碼點值又稱作為Unicode標量值(Unicode scalar values)。所以Swift中引入了 UnicodeScalar 類型,直接可用于表示某一字符的碼點值

這里直接通過UnicodeScalar的構造方法來創建一個UnicodeScalar常量對象zero,這里要注意的是,
通過UnicodeScalar構造出來的對象是一個Optional對象!

 let zero = UnicodeScalar("0")!

 // 這里使用類型標注的方式顯式給常量a聲明為UnicodeScalar類型,
 // 然后用"a"字符串字面量對它初始化
 let a: UnicodeScalar = "a"
        
 // 聲明UnicodeScalar常量π
 let π = UnicodeScalar("π")!
        
 // 聲明UnicodeScalar常量好
 let 好: UnicodeScalar = "好"
        
 // 輸出zero的標量值:48(與ASCII碼兼容)
 print("\(zero) scalar value = \(zero.value)")
        
 // 輸出a的標量值:97(與ASCII兼容)
 print("\(a) scalar value = \(a.value)")
        
 // 輸出π的標量值:960(與UCS-2兼容)
 print("\(π) scalar value = \(π.value)")
        
 // 輸出好的標量值:22909(與UCS-2兼容)
 print("\(好) scalar value = \(好.value)")
        
 let ??: UnicodeScalar = "??"
        
 // 輸出??的標量值為128516(在補充平面中)
 print("\(??) scalar value = \(??.value)")

Swift編程語言特意使用了 Character類型以覆蓋所有可被編碼的字符。這也意味著一個Character對象可包含多個UnicodeScalar對象

let flag: Character = "????"
print("flag is:\(flag)")
  
//光使用Character,我們沒有辦法獲取碼點值,所以我們這里借助String.UnicodeScalarView類型
      let scalars = flag.unicodeScalars;
      print("scalars:", separator: "", terminator: " ")
      
      // 我們這里可以發現一個很有意思的情況:
      // ????正好是由兩個Emoji字符構成:??和??
      for scalar in scalars {
          print("\(scalar)=\(scalar.value)", separator: "", terminator: " ")
      }
      
      
      let c = UnicodeScalar(127464)!
      let n = UnicodeScalar(127475)!
      print("c = \(c), n = \(n)")
      
      // 我們將兩個UnicodeScalar對應的字符對象拼在一起,
      // 構成一個String對象,
      // 然后用Character構造方法將此String對象中的內容轉換為Character相應的值
      let cn = Character(String([Character(c), Character(n)]))
      // 這里我們就能看到中國國旗的Emoji了
      print("cn = \(cn)")

二、轉義字符

    /*
    "\0" 表示空字符(null character),一般用于傳統ASCII編碼的字符串的結束符。
    "\\" 表示倒斜杠(backslash)。
    "\t" 表示水平制表符(horizontal tab)。
    "\n" 表示換行(line feed)。
    "\r" 表示回車(carriage return)。
    "\"" 表示雙引號。
    "\'" 表示單引號。當然,一般單引號在Swift編程語言中表示字符或字符串字面量時不需要做轉義,直接用 "'" 也行。”
    */
       /**
        * 這里將會輸出:
        The string is: Say, "Hello, world"!
        非常好!
        * 注意雙引號與換行符的輸出
        */
       let d = "Say,\"Hello,World!\"!\n非常好"
       print("The string is:\(d)")

三、字符串簡述

一個字符串是一組字符序列,在Swift中使用 String類型來表示一個字符串類型

***字符串的實例方法與屬性
 /*
 1.字符串與數組對象類似,也可用+操作符將兩個字符串對象拼接起來,構成一個新的字符串對象。
 2.對于一個可修改的字符串對象,則可使用 += 操作符將 += 右邊的字符串的內容添加到 += 左邊的可修改的字符串對象的末尾
 3.我們還能直接通過 == 操作符來比較兩個字符串對象中的字符序列內容是否完全相同,如果相同則返回 true,否則返回 false
 4.而要判斷一個字符串是否為空,則可使用 isEmpty 實例屬性
 5.判定字符串是否包含指定的子串,則可使用  contains(_:) 實例方法。
 6.如果我們要判斷一個字符串對象的開頭是否包含某個子串,可以使用 hasPrefix(_:) 實例方法
 7.如果我們要判斷一個字符串對象的末尾是否包含某個子串,那么可以使用 hasSuffix(_:) 實例方法。
 */
    // 這里通過 + 操作符將兩個字符串字面量拼接在一起構造出一個新的字符串對象給常量a
    let e = "Hello, " + "world!"
    // 字符串常量b則是將兩個"Hello, world!"中間用換行符連接在一起
    let f = e + "\n" + e
    print("f = \(f)")
    // 比較字符串對象a與"Hello, world!"是否相同
    // 比較結果為true
    print("Is equal? \(e == "Hello, world!")")
    // 判定字符串對象是否為空字符串
    // 結果為false
    print("Is empty? \(e.isEmpty)")
    // 判斷是否包含 , 符號
    // 結果為true
    print("contains ','? \(e.contains(","))")
    // 判斷字符串對象a是否含有前綴"Hello"
    // 結果為true
    print("Has prefix 'Hello'? \(e.hasPrefix("Hello"))")
    // 判斷字符串對象a是否含有后綴"d!"
    // 結果為true
    print("Has suffix 'd!'? \(e.hasSuffix("d!"))")
    // 這里聲明了字符串變量str,
    // 并將a的內容對它初始化
    var str = e
    // 在str對象后添加一個字符串內容
    str += " 你好,世界!"
    print("str = \(str)")

四、字符串插值

Swift編程語言提供了一種十分便利的方式可將幾乎任一類型的對象轉換為一個字符串的表示形式,這在Swift中稱為字符串插值(String Interpolation)。

        let x = 10, y = 20
        let s = "x + y = \(x+y)"
        print("s is: \(s)")
        // 當然,因為s本身是字符串類型,
        // 所以我們也可以直接用字符串拼接方式來打印
        print("s is: " + s)

五、字符串的characters屬性

如果我們想要迭代訪問一個字符串中的每個字符,或者是查詢當前字符串中包含多少字符個數,那么我們可以訪問String 對象的characters屬性。這里的 characters屬性并不是[Character] 類型,而是 String.CharacterView 類型,使得我們可以使用 for-in 循環迭代語句將其中的字符一一枚舉出,但是我們無法使用整數作為下標索引來訪問characters 中的指定字符。

        var str1 = "看旗幟:\u{1f1e8}"
        // 我們先觀察當前str對象的長度,
        // 長度為5
        print("str count: \(str1.characters.count)")
        print("before appending:", separator: "", terminator: " ")
        // 我們輸出當前str中的字符序列
        for ch in str1.characters {
            print("\(ch)", separator: "", terminator: " ")
        }
         print("")
        // 我們再新增一個字符
        str1.append("\u{1f1f3}")
        // 輸出當前字符串中字符個數,
        // 仍然為5
        print("str count: \(str1.characters.count)")
        print("After appending:", separator: "", terminator: " ")
        // 最后,我們再逐一輸出字符序列
        for ch in str1.characters {
            print("\(ch)", separator: "", terminator: " ")
        }
        print("")

String.CharacterView 類型中包含了 first屬性,可用于獲取當前字符序列中的第一個字符;另外還有 last 屬性,可用于獲取當前字符序列的最后一個字符。由于當前字符串可能是一個空串(即 ""),所以這兩個屬性的返回類型都是Optional。如果當前字符串是一個空串,那么這兩個屬性的值都是為空(nil)。我們下面來看以下代碼示例:

        let str2 = "看旗幟:\u{1f1e8}\u{1f1f3}"
        var ch = str2.characters.first!
        // 這里輸出:看
        print("first character: \(ch)")
        ch = str2.characters.last!
        // 這里輸出????的Emoji
        print("ch = \(ch)")

六、字符串的索引及字符訪問

Swift編程語言轉為String類型引入了 索引類型 String.Index 用于表示字符串對象中字符序列的索引值。由于 String.Index 類型也遵循了Comparable` 協議,所以它可以作為范圍操作符的操作數。

我們通過調用字符串對象的index(_:offsetBy:)實例方法即可得到指定的索引值。該方法的第一個參數填參考索引值,第二個參數填指定的偏移 n,偏移值為正數,說明返回的索引值往后挪 n 位,如果是負數,則說明往前挪 n 位。
String 類型還有一個index(_:offsetBy:limitedBy:)實例方法,功能與index(_:offsetBy:) 一樣,只不過這里多了一個參數,第三個參數用于做邊界檢測,如果索引計算的結果超出了第三個參數所指定的值,那么此方法將會返回空。因此它返回的是一個Optional對象。

有了索引值之后,我們就可以拿它通過字符串的 substring(with:) 實例方法獲取字符串的指定子串,然后通過子串的 characters 屬性中的first屬性或 last 屬性來獲取到當前指定的字符了。我們下面來看一個例子:

        let str3 = "看旗幟:????"
        // str字符串對象的起始索引,索引值相當于0
        let startIndex = str3.startIndex
        // str字符串對象的末尾索引,索引值相當于:
        // str.characters.count - 1
        let endIndex = str3.endIndex
        // index2作為索引2
        let index2 = str3.index(startIndex, offsetBy: 2)
        // index3作為索引3
        let index3 = str3.index(startIndex, offsetBy: 3, limitedBy: endIndex)!
        // 這里通過范圍操作符構造一個Range<String.Index>對象,
        // 作為substring方法的參數,以獲取子串。
        // 各位注意,這里必須使用 ..< 操作符,
        // 而不能使用 ... 操作符。
        // 因為 ... 操作符對應的是ClosedRange類型,
        // 而不是Range類型
        var substr = str3.substring(with: index2 ..< index3)
        // 我們這里可以觀察到,
        // substr.characters的first字符與last字符都是同一個,
        // 即“幟”這個字。
        var ch2 = substr.characters.first!
        print("ch = \(ch)")
        ch2 = substr.characters.last!
        print("ch = \(ch)")
        // 這里以index3作為參考索引,
        // 然后偏移-2表示往前移2個位置,
        // 所以index1的索引值對應的是1
        let index1 = str2.index(index3, offsetBy: -2)
        // 獲取第二個字符
        substr = str3.substring(with: index1 ..< index2)
        ch = substr.characters.first!
        // 這里輸出:
        // 第二個字符為:旗
        print("第二個字符為:\(ch)")
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容

  • 一個字符串 是一系列字符的集合,例如hello, world和albatross。Swift的字符串是String...
    BoomLee閱讀 2,413評論 0 3
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,861評論 1 10
  • 每次升級完win10系統后,我們總能在C盤下發現一個名為windows.old的文件夾,而且還占用了比較大的存儲,...
    GenomeX閱讀 5,699評論 0 2
  • 常用命令速查 . :命令可以重復上一次修改x :刪除光標下的字符u :撤銷上一次操作ctrl + r : 撤銷的撤...
    繁華落盡丶lee閱讀 354評論 0 0
  • 今天終于上了一堂回歸激情的課,找到了三年前靈動、有趣、有效的課堂感覺。美美的回味這堂課的過程。 首先是目標專一。 ...
    沐芝陽閱讀 140評論 0 3