2019-12-20 14:42:44 u012078168 阅读数 9

版本

Xcode 11.0
Swift 5.1

创建

两种方法创建:

// 1. 使用字面量
let aa = "aa"
// 2. 通过String实例化
let bb = String(aa)

创建空字符串:

let cc = ""
let dd = String()

多行字符串:

// 单行写法
let ee1 = "line1\nline2"

// 多行写法
let ee2 = """
line1
line2
"""

缩进. 从关闭引号(""")所在位置开始算每行的缩进, line1这行会被缩进

let ee3 = """
            line1
        line2
        """

续行符 (\).

let ee4 = """
line1_1 \
line1_2
"""
// 实际打印出一行 line1_1 line1_2

可变字符串

在 Objective-C 和 Cocoa 中,需要通过选择两个不同的类(NSString 和 NSMutableString)来指定字符串是否可以被修改。
Swift中, 常量不可被修改, 变量可修改.
可变字符串, 即使用var修饰字符串.

// 可变字符串
var ff = "修改前"
ff = "修改后"
print(ff)    // 打印 修改后

字符Character

// 创建字符
let aChar:Character = "!"
print(aChar)

// 使用字符数组创建字符串
let chars: [Character] = ["A", "p", "p", "l", "e"]
let str = String(chars)
print(str)

// 遍历字符串, 获取每一个字符的值
for character in "Dog!🐶" {
    print(character)
}
// D
// o
// g
// !
// 🐶

拼接

// 两个字符串直接相加
let gg = "gg"
let hh = "hh"
var ii = gg + hh
print(ii)    // 打印 gghh

// 字符串尾追加字符
let aChar: Character = "!"
ii.append(aChar)
print(ii)    // 打印 gghh!

索引/插入/删除

1. 索引
OC中, 字符串的索引是整数, 可以如下操作:

// 提取字符串:单个,指定位到末尾,开头至指定位置,指定区间
unichar aChar = [str1 characterAtIndex:5];
NSString *str4 = [str1 substringFromIndex:5];
NSString *str5 = [str1 substringToIndex:5];
NSString *str6 = [str1 substringWithRange:NSMakeRange(2, 4)];

Swift中, 字符串的索引不是整数, 而是一个索引类型String.Index。
使用 startIndex 属性可以获取一个 String 的第一个 Character 的索引。使用 endIndex 属性可以获取最后一个 Character 的后一个位置的索引。因此,endIndex 属性不能作为一个字符串的有效下标。如果 String 是空串,startIndex 和 endIndex 是相等的。

let str = "Hello, world"
let startIndex = str.startIndex
let endIndex = str.endIndex
print(startIndex)    // Index(_rawBits: 1)
print(endIndex)      // Index(_rawBits: 786433)

通过调用 String 的 index(before:) 或 index(after:) 方法,可以立即得到前面或后面的一个索引。
也可以通过调用 index(_:offsetBy:) 方法来获取对应偏移量的索引。
还可以通过调用 firstIndex(of:) 方法来获取某个字符第一次出现所对应的索引值

let str = "Hello, world"
let startIndex = str.startIndex
let endIndex = str.endIndex

// 第二个字符索引
let secondIndex = str.index(after: startIndex)
// 最后一个字符索引
let lastIndex = str.index(before: endIndex)
// 从某一索引往前/后偏移(注意偏移值可正可负)多少位所对应的索引 
let customIndex = str.index(startIndex, offsetBy: 5)
// 某一个字符在字符串中的索引
let rIndex = str.firstIndex(of: "r")    // 返回可选类型

// 打印索引对应的字符
print(str[startIndex])          // H
print(str[secondIndex])         // e
print(str[lastIndex])           // d
print(str[customIndex])         // ,
if rIndex != nil {
    print(str[rIndex!])         // r
}

遍历索引值:

// 遍历索引值
for index in str.indices {
   print("\(str[index])", terminator: "")  // 不换行打印
}
// 打印输出 Hello, world

2. 插入

// 插入字符
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome 变量现在等于 "hello!"

// 插入字符串
welcome.insert(contentsOf:" there", at: welcome.index(before: welcome.endIndex))
// welcome 变量现在等于 "hello there!"

3. 删除

// 删除字符
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome 现在等于 "hello there"

// 删除字符串
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome 现在等于 "hello"

截取 (子字符串)

在前面索引小节中, 我们知道使用数组下标方式可以获取某个index对应的字符:

let str = "Hello, world"
print(str[str.startIndex])    // H

其实也可以使用这种方式来获取字符串.
但是注意, 此时获取到的字符串属于 SubString 类型. Swift 里的 SubString 绝大部分函数都跟 String 一样,意味着你可以使用同样的方式去操作 SubString 和 String。然而, SubString 重用了原 String 的内存空间, 这意味着, 只有在短时间内需要操作字符串时才使用SubString.
为了不给自己找麻烦, 干脆把获取到的SubString直接生成一个新的可全局使用的String比较稳妥:

let str = "Hello, world"
let customIndex = str.index(str.endIndex, offsetBy: -5)
let endIndex = str.endIndex
let tempStr = str[customIndex..<endIndex]    // 返回 SubString 类型实例
print(tempStr)    // 打印输出 world

// 把SubString转化为 String 以便长期存储。
let newStr = String(tempStr)

除了使用数组下标方式, Swift还提供了两种方式来获取字符串的开头部分和结尾部分:

// 获取字符串的前5个字符
let tempStr2 = str.prefix(5)
let newStr2 = String(tempStr2)

// 获取字符串的后5个字符
let tempStr3 = str.suffix(5)
let newStr3 = String(tempStr3)

插值

字符串插值是一种构建新字符串的方式,可以在其中包含常量、变量、字面量和表达式。 你插入的字符串字面量的每一项都在以反斜线为前缀的圆括号中:

// 插值
var varA   = 20
let constA = 100
var varC:Float = 20.0

var stringA = "\(varA) 乘于 \(constA) 等于 \(varC * 100)"
print( stringA )
// 20 乘于 100 等于 2000.0

字符串比较

// 相等
let aa = "Hello"
let bb = "Hello"
if aa == bb {
    print("aa等于bb")
}

// 前缀/后缀
let cc: String = "Hello, world"
if cc.hasPrefix("He") {
    print("有前缀He")
}
if cc.hasSuffix("ld") {
    print("有后缀ld")
}

// 包含字符
if cc.contains("r") {
    print("包含字符r")
}
// 包含字符串 (要导入Foundation)
import Foundation
if cc.contains("llo") {
    print("包含字符串llo")
}

字符串函数

isEmpty
判断字符串是否为空,返回布尔值

	
hasPrefix(prefix: String)
检查字符串是否拥有特定前缀

	
hasSuffix(suffix: String)
检查字符串是否拥有特定后缀

	
Int(String)
转换字符串数字为整型

	
String.count
计算字符串的长度 (Swift 3 版本使用的是 String.characters.count)

utf8
UTF-8 编码

utf16
utf16 编码

unicodeScalars
Unicode 标量编码

字符串运算符

+
连接两个字符串,并返回一个新的字符串

+=
连接操作符两边的字符串并将新字符串赋值给左边的操作符变量

==
判断两个字符串是否相等

<
比较两个字符串,对两个字符串的字母逐一比较

!=
比较两个字符串是否不相等
2017-02-21 13:05:24 bitcser 阅读数 4425

Swift3.0语言教程替换子字符串

Swift3.0语言教程替换子字符串,替换子字符串其实就是将字符串中的子字符串删除,然后再进行添加。为了让这一繁琐的过程变的简单,NSString提供了替换子字符串的3个方法,这3个方法分别为:replacingOccurrences(of:with:)、replacingOccurrences(of:with:options:range:)和replacingCharacters(in:with:)方法。

(1)replacingOccurrences(of:with:)方法用来实现子字符串的替换,并返回一个新的字符串,其语法形式如下:

func replacingOccurrences(of target: String, with replacement: String) -> String

其中,target用来指定要替换的子字符串,replacement用来指定替换的目标字符串。

【示例1-53】以下将使用replacingOccurrences(of:with:)方法实现子字符串的替换。

import Foundation

var a=NSString(string:"Hello,Tom")

print("替换前:\(a)")

var b=a.replacingOccurrences(of: "Tom", with: "Dave")                                                     //替换

print("替换后:\(b)")

运行结果如下:

替换前:Hello,Tom

替换后:Hello,Dave

(2)replacingOccurrences(of:with:options:range:)方法和replacingCharacters(in:with:)方法类似,也是用来实现替换的。但是它比replacingCharacters(in:with:)方法多了两个参数:一个是options参数,该参数可以用来指定一个选项标记(这个标记可以作为替换的条件);另一个参数为searchRang,用来指定一个替换的范围。其语法形式如下:

func replacingOccurrences(of target: String, with replacement: String, options: NSString.CompareOptions = [], range searchRange: NSRange) -> String

【示例1-54】以下将使用replacingOccurrences(of:with:options:range:)方法实现子字符串的替换功能。

import Foundation

var a=NSString(string:"Hello,Tom")

print("替换前:\(a)")

var b=a.replacingOccurrences(of: "TOM", with: "Dave", options: NSString.CompareOptions.caseInsensitive, range: NSMakeRange(0, a.length))

print("替换后:\(b)")

运行结果如下:

替换前:Hello,Tom

替换后:Hello,Dave

(3)replacingCharacters(in:with:)方法也可以用来将指定范围的子字符串替换掉,其语法形式如下:

func replacingCharacters(in range: NSRange, with replacement: String) -> String

其中,range来指定在替换时字符集的范围,replacement用来指定替换的目标字符串。

【示例1-55】以下将使用replacingCharacters(in:with:)方法实现替换功能。

import Foundation

var a=NSString(string:"Hello,Tom")

print("替换前:\(a)")

var b=a.replacingCharacters(in: NSMakeRange(0, a.length),with: "This is book")

print("替换后:\(b)")

运行结果如下:

替换前:Hello,Tom

替换后:This is book


2019-07-15 17:08:37 PanJianlei1990 阅读数 284


字符串是诸如 “hello, world”,“abcdefg” 这样有序的字符(Character)类型的值的集合,通过 String 类型来表示。

注意:
Swift 的 String 类型与 Foundation NSString 类进行了无缝桥接。Foundation 还对 String 进行扩展使其可以访问 NSString 类型中定义的方法。这意味着调用那些 NSString 的方法,你无需进行任何类型转换。

字符串字面量

字符串字面量可以用于为常量和变量提供初始值。

let something = "Some string literal value"

多行字符串字面量

多行字符串字面量由一对三个双引号包裹着的具有固定顺序的文本字符集。

let quotation = """
The White Rabbit put on his spectacles.  "Where shall I begin,
please your Majesty?" he asked.

"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
print(quotation)

如果代码中,多行字符串字面量包含换行符的话,则多行字符串字面量中也会包含换行符。如果代码中为了增加可读性包含了换行符,但又不想在多行字符串字面量中出现换行符的话,可以在行尾写一个反斜杠(\)作为续行符。

let softWrappedQuotation = """
The White Rabbit put on his spectacles.  "Where shall I begin, \
please your Majesty?" he asked.

"Begin at the beginning," the King said gravely, "and go on \
till you come to the end; then stop."
"""

字符串字面量的特殊字符

字符串字面量可以包含以下特殊字符:
转义字符:\0(空字符)、\(反斜杠)、\t(水平制表符)、\n(换行符)、\r(回车符)、"(双引号)、’(单引号);
Unicode标量,写成\u{n}(u为小写),其中n为任意一到八位十六进制数且可用的Unicode位码。

下面的代码为各种特殊字符的使用示例。wiseWords 常量包含了两个双引号,dollarSign、blackHeart 和 sparklingHeart 常量演示了三种不同格式的 Unicode 标量:

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imageination is more important than knowledge" - Enistein
let dollarSign = "\u{24}"             // $,Unicode 标量 U+0024
let blackHeart = "\u{2665}"           // ♥,Unicode 标量 U+2665
let sparklingHeart = "\u{1F496}"      // ?,Unicode 标量 U+1F496

由于多行字符串字面量使用了三个双引号,而不是一个,所以你可以在多行字符串字面量里直接使用双引号(")而不必加上转义符(\)。要在多行字符串字面量中使用 “”" 的话,就需要使用至少一个转义符(\):

let threeDoubleQuotes = """
Escaping the first quote \"""
Escaping all three quotes \"\"\"
"""

扩展字符串分隔符

你可以将字符串文字放在扩展分隔符中,这样字符串中的特殊字符将会被直接包含而非转义后的效果。
将字符串放在引号(")中并用数字符号(#)括起来。
例如,打印字符串文字 #“Line 1 nLine 2”# 打印换行符转义序列(\n)而不是进行换行打印。

如果需要字符串文字中字符的特殊效果,请匹配转义字符(\)后面添加与起始位置个数相匹配的 # 符。
例如,如果你的字符串是 #“Line 1 nLine 2”# 并且您想要换行,则可以使用 #“Line 1 #nLine 2”# 来代替。
同样,###“Line1 ### nLine2”### 也可以实现换行效果。

扩展分隔符创建的字符串文字也可以是多行字符串文字。
你可以使用扩展分隔符在多行字符串中包含文本 “”",覆盖原有的结束文字的默认行为。例如:

let threeMoreDoubleQuotationMarks = #"""
Here are three more double quotes: """
"""#

初始化空字符串

要创建一个空字符串作为初始值,可以将空的字符串字面量赋值给变量,也可以初始化一个新的String实例。

var emptyString = ""
var anotherEmptyString = String() // 两个字符串均为空并且等价

通过检查其 Bool 类型的 isEmpty 属性来判断该字符串是否为空。

if emptyString.isEmpty {
    print("Nothing to see here")
}

字符串可变性

可以通过将一个特定字符串分配给一个变量来对其进行修改,分配给一个常量的话不能对其进行修改。

var variableString = "Horse"
variableString += " and carriage"

字符串是值类型

如果创建了一个新的字符串,那么当其进行常量、变量赋值操作,或在函数/方法中传递时,会进行拷贝。任何情况下,都会对已有字符串值创建新副本,并对该新副本进行传递或赋值操作。

在实际编译时,Swift 编译器会优化字符串的使用,使实际的复制只发生在绝对必要的情况下,这意味着你将字符串作为值类型的同时可以获得极高的性能。

使用字符

可以通过 for-in 循环来遍历字符串,获取字符串中每一个字符的值。

for character in "Dog!" {
    print(character)
}

通过标明一个 Character 类型并用字符字面量进行赋值,可以建立一个独立的字符常量或变量。

let exclamationMark: Character = "!"

字符串可以通过传递一个值类型为 Character 的数组作为自变量来初始化。

let catCharacters: [Character] = ["C", "a", "t", "!"]
let catString = String(catCharacters)

连接字符串和字符

字符串可以通过加法运算符(+)相加在一起创建一个新的字符串。

let string1 = "hello"
let string2 = "there"
var welcome = string1 + string2 // welcome 等于 "hello there"

可以通过加法赋值运算符(+=)将一个字符串添加到一个已经存在的字符串变量上。

var instruction = "look over"
instruction += string2 // instruction 等于 "look over there"

可以使用 append() 方法将一个字符附加到一个字符串变量的尾部。

welcome.append(exclamationMark) // welcome 等于 "hello there!"

如果需要使用多行字符串字面量来拼接字符串,并且需要拼接后的字符串每一行都以换行符结尾,那么前边的字符串的每一行都要以换行符结尾。

let badStart = """
one
two
"""
let end = """
three
"""
print(badStart + end)
// 打印两行
// one
// twothree
let goodStart = """
one
two

"""
print(goodStart + end)
// 打印三行
// one
// two
// three

字符串插值

字符串插值是一种构建新字符串的方式,可以在其中包含常量、变量、字面量和表达式,插入的字符串字面量的每一项都要在以反斜线为前缀的圆括号中。

let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"

注意:插值字符串中写在括号中的表达式不能包含非转义反斜杠(\),并且不能包含回车或换行符。

计算字符数量

获取一个字符串中 Character 值的数量。

let unusualMenagerie = "Koala ?, Snailm?, Penguin ?, Dromedary ?"
print(unusualMenagerie.count)

访问和修改字符串

可以通过字符串的属性和方法来访问和修改它,也可以用下标语法完成。

字符串索引

每一个 String 值都有一个关联的索引(index)类型,String.index,它对应着字符串中每一个 Character 的位置。不同的字符可能会占用不同数量的内存空间,确定 Character 的位置需要从 String 开头遍历每一个 Unicode 标量直到结尾,因此 Swif 字符串不能用整数做索引。

使用 startIndex 属性可以获取一个 String 的第一个 Character 的索引;使用 endIndex 属性可以获取最后一个 Character 的 后一个位置 的索引,endIndex 不能作为一个字符串的有效下标。如果字符串为空,startIndex 和 endIndex 是相等的。通过调用 String 的 index(before:) 或 index(after:) 方法,可以立即得到前面或后面的一个索引,可以通过调用 index(_:offsetBy:) 方法获取对应偏移量的索引,可以使用下标语法来访问 String 特定索引的 Character。

let greeting = "Guten tag!"
print(greeting[greeting.startIndex])
print(greeting[greeting.index(before: greeting.endIndex)])
print(greeting[greeting.index(after: greeting.startIndex)])
print(greeting[greeting.index(greeting.startIndex, offsetBy: 7)])
print(greeting.endIndex)

试图获取越界索引对应的 Character 将引发一个运行时错误。

使用 indices 属性会创建一个包含全部索引的范围(Range),用来在一个字符串中访问单个字符。

for index in greeting.indices {
    print("\(greeting[index]) ", terminator:"")
}

你可以使用 startIndex 和 endIndex 或者 index(before:)、index(after:) 和 index(_:offserBy:) 方法在任意一个确认的并遵循 Collection 协议的类型里面,例如在 Array、Dictionary 和 Set 中。

插入和删除

调用 insert(_:at:) 方法可以在一个字符串的指定索引插入一个字符,调用 insert(contentsOf:at:) 方法可以在一个字符串的指定索引插入一段字符串。

var welcome_ = "hello"
welcome_.insert("!", at: welcome_.endIndex)
print(welcome_)
welcome_.insert(contentsOf: " there", at: welcome_.index(before: welcome_.endIndex))
print(welcome_)

调用 remove(at:) 方法可以在一个字符串的指定索引删除一个字符,调用 removeSubrange(_? 方法可以在一个字符串的指定索引删除一个子字符串。

welcome_.remove(at: welcome_.index(before: welcome_.endIndex))
print(welcome_)
let range = welcome_.index(welcome_.endIndex, offsetBy: -6)..<welcome_.endIndex
welcome_.removeSubrange(range)
print(welcome_)

你可以使用 insert(:at:) 和 insert(contentsOf:at:)、remove(at:)、removeSubrange(? 方法在任意一个确认的并遵循 RangeReplaceableCollection 协议的类型里面,例如在 Array、Dictionary 和 Set 中。

子字符串

当你从字符串中获取一个子字符串时,可以得到一个 SubString 实例,而非另外一个 String。Swift 中的 SubString 绝大部分函数都跟 String 一样,意味着可以使用同样的的方式去操作 SubString 和 String。跟 String 不同,只有在短时间内需要操作字符串时,才会使用 SubString,需要长时间保存结果时,就把 SubString 转化为 String。

let greeting_ = "Hello, world!"
let index = greeting_.firstIndex(of: ",") ?? greeting_.endIndex
let beginning = greeting_[..<index]
let newString = String(beginning)

就像 String,每一个 SubString 都会在内存里保存字符集。而 String 和 SubString 的区别在于性能优化上,SubString 可以重用原 String 的内存空间,或者另一个 SubString 的内存空间(String 也有同样的优化,但如果两个 String 共享内存的话,它们就会相等)。这一优化意味着你在修改 String 和 SubString 之前都不需要消耗性能去复制内存。就像前面说的那样,SubString 不适合长期存储,因为它重用了原 String 的内存空间,原 String 的内存空间必须保留直到它的 SubString 不再被使用为止。

上面的例子,greeting_ 是一个 String,意味着它在内存里有一片空间保存字符集。而由于 beginning 是 greeting_ 的 SubString,它重用了 greeting_ 的内存空间。相反,newString 是一个 String,它是使用 SubString 创建的,拥有一片自己的内存空间。

注意:
String 和 SubString 都遵循 StringProtocol<//apple_ref/swift/intf/s:s14StringProtocolP> 协议,这意味着操作字符串的函数使用 StringProtocol 会更加方便。你可以传入 String 或 SubString 去调用函数。

比较字符串

Swift 提供了三种方式来比较文本值:字符串/字符相等、前缀相等、后缀相等。

字符串/字符相等

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")
}

前缀/后缀相等

通过调用字符串的 hasPrefix(? / hasSuffix(? 方法来检查字符串是否拥有特定前缀/后缀。

print(quotation_.hasPrefix("we"), quotation_.hasSuffix("and I."))

hasPrefix(? 和 hasSuffix(? 方法都是在每个字符串中逐字符比较其可扩展的字符群集是否标准相等。

2016-04-15 12:18:14 cracj 阅读数 492

        let str = "0123456��画画…………"

        let s1 = (str as NSString).substringFromIndex(3)

        print(s1)

        

        let index = str.startIndex.advancedBy(2)

        debugPrint(index.dynamicType)

        let s2 = str.substringFromIndex(index)

        print(s2)


        let tart = str.startIndex

        let end = str.endIndex.advancedBy(-1)

        let s3 = str.substringWithRange(tart..<end)

        print(s3)

没有更多推荐了,返回首页