Swift 字符(Character)

Swift 字符(Character)全解析(2025 版)

“一个 Character = 一个用户可见字符(User-Perceived Character)”
掌握 Character vs Unicode、遍历、emoji、区域标志,写出 真正国际化 的文本处理代码!


一、什么是 Character

Character 是 Swift 中表示“一个用户可见字符”的类型,它不是固定字节,而是一个扩展字形簇(Extended Grapheme Cluster)

let a: Character = "A"      // 1 个 Character
let emoji: Character = "rocket" // 1 个 Character(即使多个 Unicode 标量)
let flag: Character = "China"   // 1 个 Character(🇨🇳 = Regional Indicator C + N)

二、Character vs 其他类型

类型含义示例
Character一个用户可见字符"A", "rocket", "é"
Unicode.Scalar单个 Unicode 码点U+0061 ("a"), U+1F680 ("rocket")
UInt32码点值97
String多个 Character"Hello"
let char: Character = "cafe"
let scalar: Unicode.Scalar = "é"  // U+00E9

三、创建 Character

let a: Character = "A"
let rocket: Character = "rocket"
let snowman: Character = "snowman"

// 从 String 取第一个 Character
let first = "Swift".first!          // "S"
let last = "Swift".last!            // "t"

// 强制转换(谨慎!)
let c = Character("X")

四、遍历字符串中的 Character

let str = "Hello, Swift! rocket"

for char in str {
    print(char)  // 每个用户可见字符
}
// 输出:H e l l o ,   S w i f t !   rocket

关键for-in 遍历的是 Character不是字节或码点


五、复杂字符解析(重点!)

1. 组合字符(Combining Characters)

let eAcute = "e\u{301}"     // e + ́ (结合重音符号) = é
print(eAcute.count)         // 1(一个 Character)
print(eAcute.unicodeScalars.count)  // 2(两个标量)

2. Emoji + 皮肤修饰符

let thumbsUp = "thumbs up light skin tone"  // thumbs up + light skin tone
print(thumbsUp.count)       // 1

3. 家庭 Emoji

let family = "man woman girl boy"  // 4 人 + ZWJ = 1 个家庭
print(family.count)         // 1

4. 区域标志(国旗)

let cn = "\u{1F1E8}\u{1F1F3}"  // 🇨🇳 = Regional Indicator C + N
print(cn)                    // China
print(cn.count)              // 1

六、Character 的属性与方法

属性/方法说明
.isEmoji是否为 Emoji
.isLetter是否为字母
.isNumber是否为数字
.isWhitespace是否为空白
.unicodeScalars所有 Unicode 标量
.uppercased()转为大写
.lowercased()转为小写
let c: Character = "5"
c.isNumber      // true
c.isLetter      // false

let rocket: Character = "rocket"
rocket.isEmoji  // true

七、CharacterString 互转

// Character → String
let char: Character = "A"
let str = String(char)          // "A"

// String → Character 数组
let chars = Array("Swift")      // ["S", "w", "i", "f", "t"]

// 取第一个 Character
if let first = "Hello".first {
    print(first)  // H
}

八、常见错误 & 避坑

错误正确做法
str[0]错误!String 不支持下标
str[i]错误!必须用 index
str.count 按字节错误!count 是 Character 数
for c in str { c += "!" }错误!Characterlet

正确遍历并修改:

var result = ""
for c in "hello" {
    result += c.uppercased()
}
print(result)  // HELLO

九、高级:自定义 Character 操作

extension Character {
    var isVowel: Bool {
        return "aeiouAEIOU".contains(self)
    }

    func repeated(times: Int) -> String {
        return String(repeating: self, count: times)
    }
}

let c: Character = "A"
print(c.isVowel)        // true
print(c.repeated(times: 3))  // AAA

十、实战:字符处理工具箱

struct CharacterUtils {
    // 统计 emoji 数量
    static func countEmojis(in text: String) -> Int {
        return text.filter { $0.isEmoji }.count
    }

    // 移除所有组合标记
    static func removeCombiningMarks(from text: String) -> String {
        return text.unicodeScalars
            .filter { $0.properties.isAlphabetic || $0.properties.isDecimalDigit }
            .map { Character($0) }
            .map { String($0) }
            .joined()
    }

    // 反转字符串(正确处理 emoji)
    static func reverse(_ text: String) -> String {
        return String(text.reversed())
    }
}

// 测试
let text = "Hello rocket café China!"
print(CharacterUtils.countEmojis(in: text))  // 2
print(CharacterUtils.reverse(text))          // !anihC éfac tekor olleH

十一、性能提示

场景推荐
频繁遍历for c in str(Character)
需要码点for s in str.unicodeScalars
大量拼接var result = ""; result.reserveCapacity(n)
临时子串Substring,最后转 String

十二、Character 速查表

操作代码
创建let c: Character = "A"
遍历for c in str { }
判 Emojic.isEmoji
大写c.uppercased()
转 StringString(c)
取第一个str.first
Unicode 标量c.unicodeScalars

十三、练习题(当场写!)

// 1. 写一个函数:统计字符串中 emoji 数量
func countEmojis(_ s: String) -> Int {
    // 你的代码
}

// 2. 实现 Character 的 isConsonant 扩展(非元音字母)
extension Character {
    var isConsonant: Bool {
        // 你的代码
    }
}

// 3. 反转字符串,正确处理 "rocket café"
func reverseString(_ s: String) -> String {
    // 你的代码
}

答案(展开查看)

点击查看答案

// 1.
func countEmojis(_ s: String) -> Int {
    return s.filter { $0.isEmoji }.count
}

// 2.
extension Character {
    var isConsonant: Bool {
        let vowels = "aeiouAEIOU"
        return self.isLetter && !vowels.contains(self)
    }
}

// 3.
func reverseString(_ s: String) -> String {
    return String(s.reversed())
}

总结:Character 黄金法则

法则说明
1. Character = 用户可见字符不是字节,不是码点
2. for-in 遍历 Character自动处理组合字符
3. count 是字符数不是字节数
4. emoji、国旗、皮肤修饰符 = 1 个 Character不要拆分
5. 需要码点时用 unicodeScalars精确控制

你已完全掌握 Swift Character


回复关键词继续学习

  • Swift Unicode 深入
  • Swift 文本布局原理
  • Swift 正则与 Character
  • SwiftUI Text + Character

现在就写一个函数:输入 "Hello rocket!" → 输出 ["H","e","l","l","o"," ","rocket","!"](Character 数组)!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部