Swift 中的字符串截取

Swift 中的字符串截取

發(fā)表于2016-12-14||100

Substring in Swift 3.0

Info:

macOS 10.12.2 Beta

Xcode 8.2 Beta

Swift 3.0

前言

最近更文的頻率也是越來越慢,除去已到期末的緣故,加上在忙老師的項目,自己的時間便被壓縮殆盡。不過好在Swift 設(shè)計模式基本上已經(jīng)更新完畢,下來就準(zhǔn)備補齊每個模式對應(yīng)的說明。

在嘗試使用 Swift 實現(xiàn)《大話設(shè)計模式》一書中的解釋器模式時,書中的 Demo 多次使用了截取字符串的方法,當(dāng)然,Swift 作為一門先進的編程語言不會缺少這一常用的方法。然而在使用中,可能由于 Swift 是一門較為注重(類型)安全的語言,其字符串截取方法使用方式與 Java 等編程語言便有一些語法上的不同。在 Swift 自身的迭代過程中,這部分的語法變化也很大。所以這次就來簡單研究一下 Swift 中的字符串截取。需要注意的是,雖然 Swift 也可以使用 NSString 類型的字符串,而且兩者可以很容易的橋接,但考慮到個人對 Objective-C 的了解程度,便暫時不探討。

String.Index

Basics

索引與下標(biāo),即 index 和 subscript。一般來說,兩者的概念是類似的,不過個人覺得索引有泛指的概念,而下標(biāo)是具體的。

Swift 中字符串的索引類型并不是其他語言中的整型(int),而是 String.Index。String.Index,即標(biāo)注字符串的索引類型。在 Swift 的標(biāo)準(zhǔn)庫中,可以看到其本質(zhì)是String.CharacterView.Index的別名。

/// The index type for subscripting a string.

publictypealiasIndex=String.CharacterView.Index

再進一步查看String.CharacterView,即創(chuàng)建給定字符串的字符視圖類型。

publicstructCharacterView{

/// Creates a view of the given string.

publicinit(_text:String)

}

常用的"maimieng.com".characters的類型其實就是String.CharacterView類型。.characters將字符串內(nèi)容轉(zhuǎn)化為字符序列的視圖。

start & end

字符串必然是一個字符的有限序列,Swift 為了方便開發(fā)者迅速定位,便集成了startIndex和endIndex。但是需要注意的是:startIndex是指字符串的第一個字符的下標(biāo),而endIndex是指字符串的最后一個字符之后的下標(biāo)。當(dāng)字符串為空時,startIndex和endIndex相同。

varstr ="maimieng.com"

print(str.characters.count)

print(str.startIndex)

print(str.endIndex)

// 12

// Index(_base: Swift.String.UnicodeScalarView.Index(_position: 0), _countUTF16: 1)

// Index(_base: Swift.String.UnicodeScalarView.Index(_position: 12), _countUTF16: 0)

從上面的 Demo 也可以看出,startIndex的位置為 0,而endIndex的位置為 12,等同于字符串的長度,而不是字符串長度減一。

除了給出了起始和結(jié)尾的下標(biāo),Swift 也提供了根據(jù)下標(biāo)定位其他索引的方法:

publicfuncindex(after i: String.Index)->String.Index

publicfuncindex(before i: String.Index)->String.Index

publicfuncindex(_i: String.Index, offsetBy n: String.IndexDistance)->String.Index

publicfuncindex(_i: String.Index, offsetBy n: String.IndexDistance, limitedBy limit: String.Index)->String.Index?

這樣就可以通過給出的startIndex和endIndex來定位到其他的下標(biāo)了。

varstr ="maimieng.com"

// 返回傳入下標(biāo)之后的下標(biāo)

print(str.index(after: str.startIndex))

// 返回傳入下標(biāo)之前的下標(biāo)

print(str.index(before: str.endIndex))

// 返回傳入下標(biāo)偏移后的下標(biāo)(偏移量可正可負可為 0)

print(str.index(str.startIndex, offsetBy:1))

// print(str.index(str.endIndex, offsetBy: 10))

// 作用同上,但如果超過傳入的界限返回 nil

print(str.index(str.endIndex, offsetBy:10, limitedBy: str.endIndex) ??"越界")

下標(biāo)之間的間距,也可以利用func distance(from start: String.Index, to end: String.Index) -> String.IndexDistance方法求出:

varstr ="maimieng.com"

print(str.distance(from: str.startIndex, to: str.endIndex))

// 12

print(str.distance(from: str.endIndex, to: str.startIndex))

// -12

Range

Range 即范圍,Swift 中實現(xiàn)了 Comparable 協(xié)議的類型都可以用 Range 來表示范圍。以下的 Range 特指:Range。

Range 的構(gòu)造方法是init(uncheckedBounds bounds: (lower: Bound, upper: Bound))。即傳入一個元組,返回一個范圍。需要注意的是:這個范圍 Swift 是不會檢查的,需要程序員自覺維護。

varstr ="maimieng.com"

// 前閉后開

letrangeA =Range(uncheckedBounds: (str.startIndex, str.endIndex))

print(rangeA)

// Index(_base: Swift.String.UnicodeScalarView.Index(_position: 0), _countUTF16: 1)..

print(str.substring(with: rangeA))

// maimieng.com

// 即使范圍首尾顛倒,也沒有報錯

letrangeB =Range(uncheckedBounds: (str.endIndex, str.startIndex))

print(rangeB)

// Index(_base: Swift.String.UnicodeScalarView.Index(_position: 12), _countUTF16: 0)..

// 但在使用中會出錯

// fatal error: Can't form Range with upperBound < lowerBound

// str.substring(with: rangeB)

在上面的 Demo 中,從輸出中也可以看出,init(uncheckedBounds bounds: (lower: Bound, upper: Bound))構(gòu)造的范圍是一個前閉后開的區(qū)間。

Swift 中,字符串本身也能構(gòu)造出 Range,例如:得到字符串子串的范圍,若不存在則返回 nil:

varstr ="maimieng.com"

// 返回前閉后開的范圍

print(str.range(of:".com") ??"不存在")

// Index(_base: Swift.String.UnicodeScalarView.Index(_position: 8), _countUTF16: 1)..

substring

在 Range 一節(jié)的 Demo 中,已經(jīng)使用了substring(with:)方法測試范圍的使用。Swift 中的字符串截取與其他語言其實是相似的,都是根據(jù)索引或索引范圍來截取,只是 Swift 中的索引的類型不是整型,稍有麻煩。

varstr ="maimieng.com"

// 截取傳入范圍(左開右閉)的子串

letrange =Range(uncheckedBounds: (str.startIndex, str.endIndex))

print(str.substring(with: range))

// 從傳入的索引開始截取到末尾(含 str.startIndex 元素)

print(str.substring(from: str.startIndex))

// 從傳入的索引的前一個位置開始截取到頭部(不含 str.endIndex 元素)

print(str.substring(to: str.endIndex))

// maimieng.com

// maimieng.com

// maimieng.com

以上的 Demo 便是 Swift 中最基本的截取字符串使用。然而有時候條件一多,代碼的重復(fù)率也會增加,那么可以利用 Swift 中的

extension 來擴展原有的 String,讓 Swift 的 String 可以像 C#、Java 一樣截取字符串,需要注意的是 這里的

IndexDistance 實際上是 String.CharacterView.IndexDistance 的別名,而

String.CharacterView.IndexDistance 又是 Int 類型的別名。

extensionString{

funcsubstring(from: IndexDistance)->String? {

letindex =self.index(self.startIndex, offsetBy: from)

returnstr.substring(from: index)

}

funcsubstring(to: IndexDistance)->String? {

letindex =self.index(self.startIndex, offsetBy: to +1)

returnstr.substring(to: index)

}

funcsubstring(with range: Range)->String? {

letlower =self.index(self.startIndex, offsetBy: range.lowerBound)

letupper =self.index(self.startIndex, offsetBy: range.upperBound)

letrange =Range(uncheckedBounds: (lower, upper))

returnstr.substring(with: range)

}

funcsubstring(_lower: IndexDistance,_range: IndexDistance)->String? {

letlowerIndex =self.index(self.startIndex, offsetBy: lower)

letupperIndex =self.index(lowerIndex, offsetBy: range)

letrange =Range(uncheckedBounds: (lowerIndex, upperIndex))

returnstr.substring(with: range)

}

}

print(str.substring(to:0) ??"nil")

print(str.substring(from:2) ??"nil")

print(str.substring(with:0..<1) ??"nil")

print(str.substring(1,2) ??"nil")

// m

// imieng.com

// m

// ai

參考資料

Documentation & API Reference

原文出處:https://maimieng.com/2016/37/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 由于種種原因,簡書等第三方平臺博客不再保證能夠同步更新,歡迎移步 GitHub:https://github.co...
    萌面大道閱讀 5,649評論 2 4
  • 1 .字符串字面量 String 在Swift中字符串字面量是由雙引號" " 包裹著的 像我們在 Swift 3 ...
    iceMaple閱讀 1,226評論 1 2
  • 突然發(fā)現(xiàn),人不能閑著。因為一有空閑時間,腦子就不思考了。然后就會回憶過去,感傷現(xiàn)在,繼而胡思亂想。 畢業(yè)兩個多月的...
    Diana心情日記閱讀 244評論 0 0
  • 又和一個朋友討論了相親結(jié)婚的事,又是一個嘲諷我的理想主義的朋友...可能我對于婚姻的看法還是停留在等于愛情的階段 ...
    heim_dn閱讀 253評論 0 0

友情鏈接更多精彩內(nèi)容