news 2026/9/4 7:54:38

Swift 字符串完全指南:从基础到进阶实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Swift 字符串完全指南:从基础到进阶实战

1. 引言

字符串是 Swift 开发中使用频率最高的数据类型之一。无论是处理用户输入、解析网络数据,还是构建界面文案,字符串都扮演着核心角色。Swift 的字符串设计融合了 Unicode 标准的完整支持与高性能的底层实现,既保证了国际化场景下的正确性,又提供了简洁易用的 API。本文将从基础语法出发,逐步深入到字符串的底层原理、性能优化和实战技巧,帮助你全面掌握 Swift 字符串的使用。

2. 字符串基础

2.1 字符串的创建与初始化

Swift 提供了多种创建字符串的方式,既可以使用字符串字面量,也可以通过初始化器从其他类型转换而来。

// 使用字符串字面量创建 let greeting = "Hello, Swift!" var message = "Welcome to Swift" // 使用初始化器创建空字符串 let emptyString = String() var anotherEmpty = "" // 从其他类型转换 let number = 42 let numberString = String(number) // "42" let floatString = String(3.14) // "3.14" let charString = String(Character("A")) // "A" // 重复字符串 let stars = String(repeating: "★", count: 5) // "★★★★★" // 多行字符串字面量 let multiline = """ 这是第一行 这是第二行 这是第三行 """ print(greeting) print(numberString) print(stars) print(multiline)

2.2 字符串的可变性与值类型特性

Swift 中的字符串是值类型。当字符串被赋值给新变量或作为参数传递时,会进行值拷贝。不过 Swift 采用了写时复制(Copy-on-Write)优化,只有在字符串内容真正被修改时才会执行实际拷贝,因此这种值语义并不会带来明显的性能开销。

var original = "Hello" var copy = original // 修改 copy 不会影响 original copy.append(" World") print(original) // "Hello" print(copy) // "Hello World" // 使用 var 声明可变字符串 var mutable = "Swift" mutable += " is awesome" print(mutable) // "Swift is awesome" // 使用 let 声明不可变字符串 let constant = "Fixed" // constant += "!" // 编译错误:无法修改 let 常量

3. 字符串的遍历与字符访问

3.1 使用 for-in 遍历字符

Swift 字符串可以直接使用 for-in 循环遍历,每次迭代会取出一个 Character 类型的字符。这种遍历方式天然支持 Unicode 字符,包括 emoji 和组合字符。

let text = "Swift" for char in text { print(char) } // 输出: // S // w // i // f // t // 遍历包含 emoji 的字符串 let emojiText = "Hello 🌍" for char in emojiText { print(char) } // 输出: // H // e // l // l // o // (空格) // 🌍

3.2 字符串索引与下标访问

Swift 字符串不能直接使用整数下标访问字符,这是因为不同字符在内存中占用的字节数可能不同。Swift 提供了 String.Index 类型来安全地定位字符位置。

let str = "Swift Programming" // 获取第一个字符 let firstChar = str[str.startIndex] print(firstChar) // "S" // 获取最后一个字符 let lastChar = str[str.index(before: str.endIndex)] print(lastChar) // "g" // 获取指定偏移位置的字符 let thirdChar = str[str.index(str.startIndex, offsetBy: 2)] print(thirdChar) // "i" // 使用 indices 属性遍历所有索引 for index in str.indices { print("\(index): \(str[index])") } // 安全地访问可能不存在的索引 let safeIndex = str.index(str.startIndex, offsetBy: 100, limitedBy: str.endIndex) if let validIndex = safeIndex { print(str[validIndex]) } else { print("索引超出范围") }

4. 字符串的拼接与格式化

4.1 字符串拼接的多种方式

// 使用 + 运算符拼接 let firstName = "张" let lastName = "三" let fullName = lastName + firstName print(fullName) // "张三" // 使用 append 方法 var greeting = "Hello" greeting.append(" World") print(greeting) // "Hello World" // 使用 += 运算符 var message = "Swift" message += " is powerful" print(message) // "Swift is powerful" // 拼接不同类型需要显式转换 let age = 25 let intro = "我今年 " + String(age) + " 岁" print(intro) // "我今年 25 岁"

4.2 字符串插值

字符串插值是 Swift 中最推荐的拼接方式,它让代码更简洁、可读性更强。插值表达式可以包含变量、常量、表达式甚至函数调用。

let name = "Alice" let score = 95.5 // 基础插值 let result = "\(name) 的得分是 \(score)" print(result) // "Alice 的得分是 95.5" // 插值中执行表达式 let sum = "2 + 3 = \(2 + 3)" print(sum) // "2 + 3 = 5" // 插值中调用方法 let upper = "\(name.uppercased()) 你好" print(upper) // "ALICE 你好" // 使用自定义格式 let pi = 3.14159 let formatted = String(format: "圆周率保留两位小数:%.2f", pi) print(formatted) // "圆周率保留两位小数:3.14" // 插值中的转义 let quote = "他说:\"你好\"" print(quote) // 他说:"你好"

5. 字符串的常用操作

5.1 大小写转换与比较

let text = "Swift Programming" // 大小写转换 print(text.uppercased()) // "SWIFT PROGRAMMING" print(text.lowercased()) // "swift programming" print(text.capitalized) // "Swift Programming" // 字符串比较 let str1 = "apple" let str2 = "Apple" // 区分大小写比较 print(str1 == str2) // false // 不区分大小写比较 print(str1.caseInsensitiveCompare(str2) == .orderedSame) // true // 前缀和后缀判断 let filename = "report_2024.pdf" print(filename.hasPrefix("report")) // true print(filename.hasSuffix(".pdf")) // true // 比较运算符 print("abc" < "abd") // true,按字典序比较

5.2 查找与替换

let sentence = "The quick brown fox jumps over the lazy dog" // 查找子字符串位置 if let range = sentence.range(of: "fox") { print("找到 fox,位置:\(range)") } // 检查是否包含子字符串 print(sentence.contains("quick")) // true print(sentence.contains("cat")) // false // 替换子字符串 let replaced = sentence.replacingOccurrences(of: "fox", with: "cat") print(replaced) // "The quick brown cat jumps over the lazy dog" // 替换所有匹配项 let text2 = "apple, banana, apple, orange" let allReplaced = text2.replacingOccurrences(of: "apple", with: "pear") print(allReplaced) // "pear, banana, pear, orange" // 使用正则表达式替换 let phone = "联系电话:138-1234-5678" let cleaned = phone.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression ) print(cleaned) // "13812345678"

5.3 截取子字符串

let text = "Swift Programming Language" // 截取前 5 个字符 let prefix = text.prefix(5) print(prefix) // "Swift" // 截取后 9 个字符 let suffix = text.suffix(9) print(suffix) // "Language" // 截取中间部分 let start = text.index(text.startIndex, offsetBy: 6) let end = text.index(text.startIndex, offsetBy: 17) let middle = text[start..<end] print(middle) // "Programming" // 使用 prefix(upTo:) 和 suffix(from:) let upTo = text.prefix(upTo: text.index(text.startIndex, offsetBy: 5)) print(upTo) // "Swift" let from = text.suffix(from: text.index(text.startIndex, offsetBy: 6)) print(from) // "Programming Language" // 注意:substring 与原字符串共享内存 let substring = text.prefix(5) let newString = String(substring) // 转换为独立 String print(newString) // "Swift"

6. 字符串与集合的转换

6.1 字符串与数组的互转

// 字符串转字符数组 let text = "Hello" let charArray = Array(text) print(charArray) // ["H", "e", "l", "l", "o"] // 字符串按分隔符拆分为数组 let csv = "apple,banana,orange" let fruits = csv.components(separatedBy: ",") print(fruits) // ["apple", "banana", "orange"] // 使用 split 方法(返回 Substring 数组) let sentence = "Swift is a powerful language" let words = sentence.split(separator: " ") print(words) // ["Swift", "is", "a", "powerful", "language"] // 数组拼接为字符串 let items = ["Swift", "Kotlin", "Java"] let joined = items.joined(separator: ", ") print(joined) // "Swift, Kotlin, Java" // 字符数组转字符串 let chars: [Character] = ["S", "w", "i", "f", "t"] let fromChars = String(chars) print(fromChars) // "Swift"

6.2 字符串与字典的转换

// 将键值对字符串解析为字典 let queryString = "name=Alice&age=25&city=Beijing" var params: [String: String] = [:] for pair in queryString.split(separator: "&") { let keyValue = pair.split(separator: "=") if keyValue.count == 2 { let key = String(keyValue[0]) let value = String(keyValue[1]) params[key] = value } } print(params) // ["name": "Alice", "age": "25", "city": "Beijing"] // 字典转查询字符串 let dict = ["name": "Bob", "age": "30"] let query = dict.map { "\($0.key)=\($0.value)" } .joined(separator: "&") print(query) // "name=Bob&age=30"

7. Unicode 与国际化处理

7.1 Unicode 标量与字符

// 查看字符串的 Unicode 标量 let text = "Swift" for scalar in text.unicodeScalars { print("\(scalar) = U+\(String(scalar.value, radix: 16).uppercased())") } // 输出: // S = U+53 // w = U+77 // i = U+69 // f = U+66 // t = U+74 // 使用 Unicode 转义序列 let heart = "\u{2665}" print(heart) // "♥" // 组合字符 let eAcute = "\u{E9}" // é let eCombined = "e\u{301}" // e + 重音符号 print(eAcute == eCombined) // true,两者表示相同的字符 // 查看字符数量 let flag = "🇨🇳" print(flag.count) // 1,旗帜 emoji 是一个字符 print(flag.unicodeScalars.count) // 2,由两个 Unicode 标量组成

7.2 字符串长度与字节数

let text = "Hello, 世界! 🌍" // 字符数量(用户感知的字符数) print(text.count) // 11 // UTF-8 字节数 print(text.utf8.count) // 19 // UTF-16 单元数 print(text.utf16.count) // 12 // 遍历 UTF-8 字节 for byte in text.utf8 { print(byte, terminator: " ") } print() // 输出:72 101 108 108 111 44 32 228 184 150 231 149 140 33 32 240 159 140 141

8. 字符串性能优化

8.1 避免不必要的字符串拷贝

// 使用 Substring 避免拷贝 let fullText = "这是一个非常长的字符串,包含大量文本内容" let startIndex = fullText.startIndex let endIndex = fullText.index(startIndex, offsetBy: 5) // Substring 共享原字符串的内存 let substring = fullText[startIndex..<endIndex] print(substring) // "这是一" // 需要长期持有或修改时再转换为 String let newString = String(substring) // 避免在循环中频繁拼接字符串 var result = "" for i in 0..<1000 { // 每次 += 都可能触发内存重新分配 result += "\(i) " } // 推荐:使用数组收集再一次性拼接 var parts: [String] = [] for i in 0..<1000 { parts.append("\(i)") } let optimized = parts.joined(separator: " ")

8.2 使用 String 的高效方法

// 使用 contains 而不是 range(of:) 判断存在性 let text = "Swift Programming" if text.contains("Swift") { print("包含 Swift") } // 使用 hasPrefix/hasSuffix 进行快速判断 let url = "https://example.com" if url.hasPrefix("https://") { print("安全链接") } // 批量替换使用 replacingOccurrences let original = "a-b-c-d-e" let replaced = original.replacingOccurrences(of: "-", with: "+") print(replaced) // "a+b+c+d+e" // 使用 String 的 withCString 与 C 语言交互 let cString = "Hello" cString.withCString { pointer in // 在这里使用 C 字符串指针 print("C 字符串长度:\(strlen(pointer))") }

9. 实战案例:文本处理工具

9.1 单词统计器

struct WordCounter { static func countWords(in text: String) -> [String: Int] { var wordCount: [String: Int] = [:] // 按空格和标点拆分 let words = text.split { !$0.isLetter } for word in words { let lowercased = word.lowercased() wordCount[lowercased, default: 0] += 1 } return wordCount } static func topWords(in text: String, limit: Int) -> [(word: String, count: Int)] { let counts = countWords(in: text) return counts.sorted { $0.value > $1.value } .prefix(limit) .map { (word: $0.key, count: $0.value) } } } let sampleText = """ Swift is a powerful language. Swift is also easy to learn. Swift supports protocol-oriented programming. """ let topWords = WordCounter.topWords(in: sampleText, limit: 5) for item in topWords { print("\(item.word): \(item.count) 次") } // 输出: // swift: 3 次 // is: 2 次 // a: 1 次 // powerful: 1 次 // language: 1 次

9.2 字符串验证器

struct StringValidator { // 验证邮箱格式 static func isValidEmail(_ email: String) -> Bool { let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" let predicate = NSPredicate(format: "SELF MATCHES %@", pattern) return predicate.evaluate(with: email) } // 验证手机号(中国大陆) static func isValidPhoneNumber(_ phone: String) -> Bool { let pattern = "^1[3-9]\\d{9}$" return phone.range(of: pattern, options: .regularExpression) != nil } // 验证密码强度 static func passwordStrength(_ password: String) -> String { var score = 0 if password.count >= 8 { score += 1 } if password.range(of: "[A-Z]", options: .regularExpression) != nil { score += 1 } if password.range(of: "[a-z]", options: .regularExpression) != nil { score += 1 } if password.range(of: "[0-9]", options: .regularExpression) != nil { score += 1 } if password.range(of: "[^A-Za-z0-9]", options: .regularExpression) != nil { score += 1 } switch score { case 0...2: return "弱" case 3...4: return "中" default: return "强" } } } print(StringValidator.isValidEmail("user@example.com")) // true print(StringValidator.isValidEmail("invalid-email")) // false print(StringValidator.isValidPhoneNumber("13812345678")) // true print(StringValidator.passwordStrength("Swift123!")) // 强

9.3 字符串编码转换工具

struct EncodingHelper { // Base64 编码 static func base64Encode(_ text: String) -> String? { guard let data = text.data(using: .utf8) else { return nil } return data.base64EncodedString() } // Base64 解码 static func base64Decode(_ base64: String) -> String? { guard let data = Data(base64Encoded: base64) else { return nil } return String(data: data, encoding: .utf8) } // URL 编码 static func urlEncode(_ text: String) -> String { var allowed = CharacterSet.alphanumerics allowed.insert(charactersIn: "-._~") return text.addingPercentEncoding(withAllowedCharacters: allowed) ?? text } // URL 解码 static func urlDecode(_ text: String) -> String { return text.removingPercentEncoding ?? text } // 十六进制编码 static func hexEncode(_ text: String) -> String { return text.unicodeScalars.map { String(format: "%04X", $0.value) }.joined() } } let original = "Hello, Swift! 你好,世界!" let encoded = EncodingHelper.base64Encode(original)! print("Base64: \(encoded)") print("解码: \(EncodingHelper.base64Decode(encoded)!)") let urlString = "https://example.com/search?q=Swift 字符串" let urlEncoded = EncodingHelper.urlEncode(urlString) print("URL 编码: \(urlEncoded)") print("URL 解码: \(EncodingHelper.urlDecode(urlEncoded))") print("Hex: \(EncodingHelper.hexEncode("AB"))") // "00410042"

10. 总结

Swift 字符串是一个功能强大且设计精良的数据类型。通过本文的学习,我们掌握了字符串的创建、遍历、拼接、格式化、查找替换、截取等核心操作,理解了 Unicode 处理机制和值类型特性,并学习了性能优化的关键技巧。在实际开发中,建议根据具体场景选择合适的字符串操作方式:频繁拼接时使用数组收集再一次性拼接,需要子串时优先使用 Substring 避免不必要的拷贝,处理用户输入时注意 Unicode 字符的边界情况。希望本文的代码示例能够帮助你在实际项目中更加高效地使用 Swift 字符串。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 7:53:52

单片机智能养生壶控制系统设计:从硬件选型到PID温控算法实践

简介&#xff1a;本资源是一套面向电子类专业本科生及单片机初学者的家用养生壶自动控制系统完整设计资料&#xff0c;基于51单片机实现多模式智能温控&#xff0c;解决传统养生壶功能单一、操作繁琐的问题&#xff0c;适用于课程设计、毕业设计及嵌入式实践项目。压缩包共77个…

作者头像 李华
网站建设 2026/9/4 7:53:21

STM32F103+EC20 TCP透传实战:工业4G通信稳定落地指南

简介&#xff1a;本资源是一套面向嵌入式物联网开发者的STM32F103单片机驱动移远EC20 4G模块实现TCP透传通信的完整工程代码例程&#xff0c;适用于工业数据上报、远程终端监控等典型物联网应用场景&#xff0c;适合具备C语言基础与STM32外设开发经验的中级工程师及高校实践学习…

作者头像 李华
网站建设 2026/9/4 7:53:04

私有RAG知识库系统:本地部署的智能问答实战方案

简介&#xff1a;本资源是一套基于RAG技术构建的私有知识库智能问答系统完整实现&#xff0c;面向高校毕业设计、AI工程实践者及大模型应用开发者&#xff0c;解决本地化知识检索与大模型协同推理落地难的问题。压缩包含467个文件&#xff0c;总大小107.26MB&#xff0c;涵盖14…

作者头像 李华
网站建设 2026/9/4 7:50:09

Spark 思想表达力平台(星火计划) 下

中国年轻一代正面临"思想消费"与"思想产出"之间的巨大鸿沟。现有AI口语产品大多停留在"跟读纠音"层面&#xff0c;缺乏将知识输入转化为观点表达的能力闭环。AI辅助学习者的流利度提升是传统方法的数倍&#xff0c;但"表达深度"这一关…

作者头像 李华
网站建设 2026/9/4 7:49:43

ZYNQ7100 DDR3系统级配置与实战避坑指南

简介&#xff1a;本资源是面向FPGA工程师与嵌入式系统开发者的ZYNQ-7000系列高性能DDR3内存控制器实战项目&#xff0c;聚焦ZYNQ7100&#xff08;XC7Z100FFG900-2&#xff09;平台在Vivado环境下实现稳定、可复用的DDR3读写功能&#xff0c;解决高速存储接口时序约束、PS/PL协同…

作者头像 李华
网站建设 2026/9/4 7:45:31

移动机械硬盘怎么选?从SMR/CMR到SMART检测全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华