Swift 常用字符串操作
2016-06-17 17:28
483 查看
原文链接:http://www.jianshu.com/p/52e7580166ff
版本2:增加了Swift 2.0的语法,与Swift 1.2的语法相比,主要是:advance方法变成了advancedBy方法(但不是简单替换);没有了count方法,count(str)需要变成str.characters.count等。
字符串的定义
字符的定义
字符串的连接
字符串与字符的连接
字符串与其它类型值的连接
字符串枚举字符
获取字符串中指定索引处的字符
计算字符串长度length
字符串比较
是否包含子串contains
查找子串indexof
首字母大写capitalized
转换为大写字母uppercase
转换为小写字母lowercase
截取字符串substring
字符串修剪trim
字符串的分解子串split
字符串替换replace
string转换为Int/Long/Float/Double/Bool等
Swift 的语法一直都在演变进化,在1.x到2.x的演变过程中也发生了很大的改变,在开源后发展更加迅速,即将发布的3.0版本也合并到了master.
字符串的处理也是变化的一部分,在最近的coding中遇到了一些频繁需要字符串处理的地方,过程中发现目前版本(2.x)字符串处理的语法实在有些啰嗦。
在Swift1.0 的时候字符串的截取是这样的:
如果在Swift2.x可以,那真是极好的。
我喜欢这种以自然数提取字符串的方式,可是在Swift2.x中已经摒弃。
在Swift2.x中需要这样写:
或者更简单点:
当然用OC中的NSString也是可以的,只是...
因为在Swift2.x (应该是在Swift1.2以后吧)中用String.Index代替了自然数, 新的API 毫无疑问的会占用我仅仅16GB的记忆量,我不想调用新API中那些所谓的牛逼黑科技代码。
为什么一个简单的字符串处理需要写的这么啰嗦,这里很好的总结了这一切
其实我更喜欢python截取字符串的风格,简单粗暴。
所以我决定对它做些改变:
Swift中的扩展可以:
添加计算型属性和计算型类型属性
定义实例方法和类型方法
提供新的构造器
定义下标
定义和使用新的嵌套类型
使一个已有类型符合某个协议
下标可以定义在类(class)、结构体(structure)和枚举(enumeration)中,是访问集合(collection),列表(list)或序列(sequence)中元素的快捷方式。
我现在添加String的扩展来定义下标,然后取出想要的字符串,下标接收Int类型的Range,Index 通过
successor() 和 predecessor() 分别是可能出现的下一个值,和上一个值。
自然数截取 极好的.
然而发现了问题,我要像python用下标从后向前取怎么办 :|
不用Range 就是了:) 下面我将重新写一个接收两个参数下标方法,注意, 这里通过三元表达式来判断。在end 小于 0 时会 执行
搞定!不过参数中
自定义运算符可以由以下的 ASCII 字符
支持一元前缀 prefix (例如 --a, ++a, ! false)、一元后缀 postfix (a--, a++)、二元中置 infix (a+b, a-b, a==b)运算符
支持自定义优先级
在Swift中
没错,我在下标方法加了个set 方法用来替换指定下标的值。
可能有人对
我们可能还会需要经常的获取字符的下标,这是Swift 中正常获取字符所在下标的方法:
是的,我们没法通过上面的方法去直接获得自然数的下标,所以就有了下面的扩展方法:
当然接下来可以玩的还有很多
比如字符串替换:
原文链接:http://www.jianshu.com/p/52b7b333d41c
版本2:增加了Swift 2.0的语法,与Swift 1.2的语法相比,主要是:advance方法变成了advancedBy方法(但不是简单替换);没有了count方法,count(str)需要变成str.characters.count等。
字符串的定义
var str1="hello, mandarava." //字符串变量 let str2="hello, mandarava." //字符串常量 let str3="" //空字符串 let str4=String() //空字符串
字符的定义
var char1:Character="m" //字符变量 let char2:Character="m" //字符常量
字符串的连接
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"
字符串与字符的连接
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"
字符串与其它类型值的连接
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=?"
字符串枚举字符
//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) }
获取字符串中指定索引处的字符
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"
计算字符串长度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
字符串比较
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
是否包含子串contains
let str1="hello,mandarava." let str2="mandarava" let range=str1.rangeOfString(str2) if range != nil{ //包含 }
查找子串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
首字母大写capitalized
var str1="mandarava is a flower." str1.capitalizedString //str1="Mandarava Is A Flower.
转换为大写字母uppercase
var str1="hello, mandarava." str1=str1.uppercaseString //str1="HELLO, MANDARAVA."
转换为小写字母lowercase
var str1="HELLO, MANDARAVA." str1=str1.lowercaseString //str1="hello, mandarava."
截取字符串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"
字符串修剪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."
字符串的分解子串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"]
字符串替换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."
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
相关文章推荐
- swift学习之路(十八)泛型
- swift2.0 学习笔记Seventeen
- 从零开始学swift 第一篇 环境安装
- swift学习之路(十七)协议
- ReactNative-Cocoapods-Swift-Project
- swift学习03-可选类型Optional
- swift简单瀑布流的实现
- 深入探究Swift数组背后的协议、方法、拓展(转)
- swift 二维码扫描
- 真机调试Swift项目(47K),存储空间占了16M!!!
- 初学swift
- [Swift 开发] 使用闭包传值(typealias)
- swift第一季基础语法
- Oc与swift区别
- swift2.0 学习笔记Sixteen
- iOS动画学习笔记3 Video Tutorial iOS Animation with Swift - Ray Wenderlich
- [IOS/Swift]'Project Name' was compiled with optimization
- swift学习笔记2——函数、闭包
- Swift-基础-6
- Swift-基础-5