Swift 常用字符串操作


原文鏈接:http://www.jianshu.com/p/52e7580166ff

版本2:增加了Swift 2.0的語法,與Swift 1.2的語法相比,主要是:advance方法變成了advancedBy方法(但不是簡單替換);沒有了count方法,count(str)需要變成str.characters.count等。

  1. 字符串的定義
    var str1="hello, mandarava." //字符串變量 let str2="hello, mandarava." //字符串常量 let str3="" //空字符串 let str4=String() //空字符串
  2. 字符的定義
    var char1:Character="m" //字符變量 let char2:Character="m" //字符常量
  3. 字符串的連接
    let str1="hello, " let str2="mandarava." let str3=str1+str2 //=連接str1、str2 //str3="hello, mandarava." //---------------------------------------- let str4="\(str1)\(str2)" //=連接str1、str2 //str4="hello, mandarava." //---------------------------------------- let strArray=["apple", "orange", "cherry"] let joinStr=",".join(strArray) //joinStr="apple,orange,cherry"
  4. 字符串與字符的連接
    let char1:Character="o" var str1="hell" let str2=str1+String(char1) //str2="hello" //---------------------------------------- let str3="\(str1)\(char1)" //str3="hello" //---------------------------------------- str1.append(char1) //str1="hello"
  5. 字符串與其它類型值的連接
    let xx=10 let yy=10.8 let str1="\(xx)+\(yy)=?" //str1="10+10.8=?" //---------------------------------------- let str2=String(format: "%i+%.1f=?", xx, yy) //str2="10+10.8=?"
  6. 字符串枚舉字符
    //Swift 1.2 let str="mandarava" for ch in str{ println(ch) } //----------------------- //Swift 2.0 let str="mandarava" for ch in str.characters{ print(ch) }
  7. 獲取字符串中指定索引處的字符
    let str="Mandarava" let chr=str[advance(str.startIndex,2)] //Swift 1.2 //chr:Character="n" let chr=str[str.startIndex.advancedBy(2)] //Swift 2.0 //chr:Character="n"
  8. 計算字符串長度length
    let str="@鰻駝螺" let len1=count(str) //swift 1.2 //=4 let len2=str.characters.count //swift 2.0 //=4 let blen=str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) //=10
  9. 字符串比較
    let str1="hello," let str2="mandarava." let str3="hello,mandarava." let comp1 = str1==str2 //false let comp2 = str1+str2 == str3 //true let comp3 = str1 < str2 //true let comp4 = str1 != str2 //true
  10. 是否包含子串contains
    let str1="hello,mandarava." let str2="mandarava" let range=str1.rangeOfString(str2) if range != nil{ //包含 }
  11. 查找子串indexof
    var str="hi,Mandarava." let range=str.rangeOfString("Mandarava", options: NSStringCompareOptions.allZeros) //Swift 1.2 let range=str.rangeOfString("Mandarava", options: NSStringCompareOptions()) //Swift 2.0 let startIndex=range?.startIndex //=3
  12. 首字母大寫capitalized
    var str1="mandarava is a flower." str1.capitalizedString //str1="Mandarava Is A Flower.
  13. 轉換為大寫字母uppercase
    var str1="hello, mandarava." str1=str1.uppercaseString //str1="HELLO, MANDARAVA."
  14. 轉換為小寫字母lowercase
    var str1="HELLO, MANDARAVA." str1=str1.lowercaseString //str1="hello, mandarava."
  15. 截取字符串substring
    let str1="hello,mandarava." let str2=str1.substringFromIndex(advance(str1.startIndex, 6)) //Swift 1.2 let str2=str1.substringFromIndex(str1.startIndex.advancedBy(6)) //Swift 2.0 //str2="mandarava." //---------------------------------------- let str3=str1.substringToIndex(advance(str1.startIndex, 5)) //Swift 1.2 let str3=str1.substringToIndex(str1.startIndex.advancedBy(5)) //Swift 2.0 //str3="hello" //---------------------------------------- let range=Range<String.Index>(start: advance(str1.startIndex, 6), end: advance(str1.endIndex, -1)) //Swift 1.2 let range=Range<String.Index>(start: str1.startIndex.advancedBy(6), end: str1.endIndex.advancedBy(-1)) //Swift 2.0 let str4=str1.substringWithRange(range) //str4="mandarava"
  16. 字符串修剪trim
    let str1=" mandarava.\n " let str2=str1.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) //str2="mandarava." //---------------------------------------- let str3=str1.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) //str3="mandarava.\n" //---------------------------------------- let charset=NSCharacterSet(charactersInString:" \n") let str4=str1.stringByTrimmingCharactersInSet(charset) //str4="mandarava."
  17. 字符串的分解子串split
    var str1="boy, girl, man, woman" let str1Array=str1.componentsSeparatedByString(",") //str1Array=["boy", " girl", " man", " woman"] var str2="boy,girl,man 10 20 30" let charset=NSCharacterSet(charactersInString:", ") let str2Array=str2.componentsSeparatedByCharactersInSet(charset) //str2Array=["boy", "girl", "man", "10", "20", "30"]
  18. 字符串替換replace
    var str1="My name is Mandarava." let subRange=Range(start: str1.startIndex, end: advance(str1.startIndex, 2)) //Swift 1.2 let subRange=Range(start: str1.startIndex, end: str1.startIndex.advancedBy(2)) //Swift 2.0 str1.replaceRange(subRange, with: "Your") //str1="Your name is Mandarava." var str2="hello, Mandarava." str2=str2.stringByReplacingOccurrencesOfString("Mandarava", withString: "鰻駝螺") //str2="hello, 鰻駝螺." str2=str2.stringByReplacingOccurrencesOfString("鰻駝螺", withString: "Mandarava", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil) //str2="hello, Mandarava."
  19. string轉換為Int/Long/Float/Double/Bool等
    var str1="100" var i=str1.toInt()! //Swift 1.2 //=100 var i=(str1 as NSString).integerValue //Swift 2.0 //=100 var i=(str1 as NSString).intValue //=100 var l=(str1 as NSString).longLongValue //=100 var str2="10.8" var f=(str2 as NSString).floatValue //=10.8 var d=(str2 as NSString).doubleValue //=10.8 var str3="true" var b=(str3 as NSString).boolValue //=true





Swift 的語法一直都在演變進化,在1.x到2.x的演變過程中也發生了很大的改變,在開源后發展更加迅速,即將發布的3.0版本也合並到了master.
字符串的處理也是變化的一部分,在最近的coding中遇到了一些頻繁需要字符串處理的地方,過程中發現目前版本(2.x)字符串處理的語法實在有些啰嗦。

在Swift1.0 的時候字符串的截取是這樣的:

var hp = "Hello, playground" let hello = hp[0 ... 4] // error

如果在Swift2.x可以,那真是極好的。

我喜歡這種以自然數提取字符串的方式,可是在Swift2.x中已經摒棄。

在Swift2.x中需要這樣寫:

let hello = hp.substringWithRange(Range<String.Index>(start: hp.startIndex, end: hp.startIndex.advancedBy(5))) // "Hello"

或者更簡單點:

let hello = hp[hp.startIndex..<hp.startIndex.advancedBy(5)] // "Hello"

當然用OC中的NSString也是可以的,只是...

var nsHp = hp as NSString let hello = nsHp.substringWithRange(NSMakeRange(0, 5)) // "Hello"

因為在Swift2.x (應該是在Swift1.2以后吧)中用String.Index代替了自然數, 新的API 毫無疑問的會占用我僅僅16GB的記憶量,我不想調用新API中那些所謂的牛逼黑科技代碼。

為什么一個簡單的字符串處理需要寫的這么啰嗦,這里很好的總結了這一切

其實我更喜歡python截取字符串的風格,簡單粗暴。

hp = "Hello, playground" hello = hp[0:5] // "Hello" hello = hp[0:-12] // "Hello"

所以我決定對它做些改變:

擴展 Extension

Swift 中的擴展和 Objective-C 中的分類類似,(只是Swift 中擴展沒有名字)

Swift中的擴展可以:

  • 添加計算型屬性和計算型類型屬性
  • 定義實例方法和類型方法
  • 提供新的構造器
  • 定義下標
  • 定義和使用新的嵌套類型
  • 使一個已有類型符合某個協議

下標 Subscripts

下標可以定義在類(class)、結構體(structure)和枚舉(enumeration)中,是訪問集合(collection),列表(list)或序列(sequence)中元素的快捷方式。

我現在添加String的擴展來定義下標,然后取出想要的字符串,下標接收Int類型的Range,Index 通過advancedBy(n)來遞增,參數n是前進的個數,如果 n 大於 0 則會調用self的 successor() n 次,小於 0 則會調用 predecessor() n 次。

successor() 和 predecessor() 分別是可能出現的下一個值,和上一個值。

extension String { subscript (r: Range<Int>) -> String { get { let startIndex = self.startIndex.advancedBy(r.startIndex) let endIndex = self.startIndex.advancedBy(r.endIndex) return self[Range(start: startIndex, end: endIndex)] } } } let hello1 = hp[Range(start: 0, end: 5)] // "Hello" let hello2 = hp[0 ..< 5] // "Hello"

自然數截取 極好的.

然而發現了問題,我要像python用下標從后向前取怎么辦 :|

let hello = hp[0 ..< -12] // "error" ( system:不懂Range 別亂搞 :( )

不用Range 就是了:) 下面我將重新寫一個接收兩個參數下標方法,注意, 這里通過三元表達式來判斷。在end 小於 0 時會 執行self.endIndex.advancedBy(end) , 前面有說到,也就是說會執行abs(end)次的predecessor()方法。

extension String {
  subscript (start: Int, end: Int) -> String { let s = self.startIndex.advancedBy(start) let e = end < 0 ? self.endIndex.advancedBy(end) : self.startIndex.advancedBy(end) return self[Range(start: s, end: e)] } } let hello = hp[0, -12] // "Hello"

搞定!不過參數中[0, -12]中間的, 讓整體像個Array ,感覺怪怪的,我不太喜歡,決定改掉。

自定義運算符

  • 自定義運算符可以由以下的 ASCII 字符 /、=、 -、+、!、*、%、<、>、&、|、^、? 、~自由組合.
  • 支持一元前綴 prefix (例如 --a, ++a, ! false)、一元后綴 postfix (a--, a++)、二元中置 infix (a+b, a-b, a==b)運算符
  • 支持自定義優先級

注:操作符前后空格也有規則,這里不多做說明,可自行查看官方文檔。

在Swift中 : 歸為字符,而非運算符,所以無法使用,我覺定用~來替代,創建一個二元中置運算符:

infix operator ~ {
  precedence 250  // 優先級 0~255 的一個值,具體參考官方文檔 associativity none // 結合 left, right, none } func ~(start: Int, end: Int) -> (s: Int, e: Int) { return (start, end) // 說好的運算符,除了返回個元組,啥也沒干... } extension String { //接收元組的下標方法 subscript (myRange: (s: Int, e: Int)) -> String { get { let s = self.startIndex.advancedBy(myRange.s) let e = myRange.e < 0 ? self.endIndex.advancedBy(myRange.e) : self.startIndex.advancedBy(myRange.e) return self[Range(start: s, end: e)] } set { let s = self.startIndex.advancedBy(myRange.s) let e = myRange.e < 0 ? self.endIndex.advancedBy(myRange.e) : self.startIndex.advancedBy(myRange.e) str.replaceRange(Range(start: s, end: e), with: newValue) } } } let hello = hp[0 ~ 5] // "Hello" hp[7 ~ 17] = "dimsky" // "Hello, dimsky"

沒錯,我在下標方法加了個set 方法用來替換指定下標的值。

可能有人對 advanceBy 這個方法還不太理解,下面我將用 + 運算符來替代這個方法:

func +<T: BidirectionalIndexType>(var index: T, count: Int) -> T { let num = abs(count) for _ in 0..<num { index = count < 0 ? index.predecessor() : index.successor() } return index } let hello = str[str.startIndex ..< str.startIndex.advancedBy(5)] // "hello" let play = str[str.startIndex + 7 ..< str.startIndex + 11] // "play" let play2 = str[str.startIndex + 7 ..< str.endIndex + -6] // "play" let helloPlay = str[str.startIndex ..< str.endIndex.advancedBy(-6)] // "Hello, play"

我們可能還會需要經常的獲取字符的下標,這是Swift 中正常獲取字符所在下標的方法:

let index1 = hp.rangeOfString("H")?.startIndex // 0 (String.CharacterView.Index) let index2 = hp.rangeOfString("o")?.endIndex // 5 (String.CharacterView.Index)

是的,我們沒法通過上面的方法去直接獲得自然數的下標,所以就有了下面的擴展方法:

extension String { func indexOfString(target: String) -> Int { let range = self.rangeOfString(target) if let range = range { return self.startIndex.distanceTo(range.startIndex) } else { return -1 } } } let index = hp.indexOfString("o") // 5 (Int)

當然接下來可以玩的還有很多
比如字符串替換:

hp["playground"] = "三上悠亞" // waiting for you to complete hp.stringByReplacingOccurrencesOfString("playground", withString: "鈴原エミリ") // "Hello, 鈴原エミリ" 延用了OC的API


原文鏈接:http://www.jianshu.com/p/52b7b333d41c


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM