Shaula Blog

美丽的东西都是肤浅的

Swift 中的 Scanner 类

Scanner 是 Swift 标准库中一个用于解析结构化字符串的实用工具类。它能够逐步扫描字符串内容,并从中提取特定类型的数据(如整数、浮点数、子字符串等),特别适用于处理格式化文本数据或自定义协议解析。

核心功能

Scanner 的主要作用是将字符串分解为多个有意义的组成部分。与手动使用 splitcomponents(separatedBy:) 方法相比,Scanner 提供了以下优势:

  • 类型安全:可以直接提取目标数据类型(如 IntDouble 等)。
  • 状态管理:自动记录当前扫描位置,支持回溯和跳跃。
  • 灵活配置:可自定义字符集以控制扫描行为。

基本用法

初始化

let inputString = "42 3.14 Hello"
let scanner = Scanner(string: inputString)

// 可选配置(如忽略大小写)
scanner.caseSensitive = false

扫描方法

  • 扫描基础类型

    var intValue: Int = 0
    if scanner.scanInt(&intValue) {
        print("找到整数: \(intValue)") // 输出 42
    }
    
    var doubleValue: Double = 0
    if scanner.scanDouble(&doubleValue) {
        print("找到浮点数: \(doubleValue)") // 输出 3.14
    }
    
  • 扫描字符串

    var scannedString: NSString?
    if scanner.scanUpToCharacters(from: .whitespaces, into: &scannedString) {
        print("找到字符串: \(scannedString!)") // 输出 "Hello"
    }
    

高级特性

字符集控制

// 跳过特定字符
scanner.charactersToBeSkipped = .whitespaces

// 扫描到特定字符为止
var result: NSString?
scanner.scanUpTo("!", into: &result)

位置控制

// 获取/设置当前扫描位置
let currentIndex = scanner.currentIndex
scanner.currentIndex = inputString.startIndex

// 判断是否扫描完成
if scanner.isAtEnd {
    print("扫描完成")
}

解析坐标字符串

let coordinateString = "(x: 12.5, y: -45.2)"
let coordScanner = Scanner(string: coordinateString)

coordScanner.scanString("(", into: nil)
coordScanner.scanString("x:", into: nil)

var x: Double = 0
coordScanner.scanDouble(&x)

coordScanner.scanString(", y:", into: nil)

var y: Double = 0
coordScanner.scanDouble(&y)

print("解析坐标: (\(x), \(y))") // 输出 (12.5, -45.2)

注意事项

  1. 错误处理:需检查每个扫描操作的返回值。
  2. 线程安全Scanner 不是线程安全的,需自行处理同步。
  3. 编码问题:默认使用字符串的 Unicode 编码。
  4. 性能优化:适合中等规模数据,超长字符串建议分块处理。

总结

通过合理使用 Scanner,开发者可以避免复杂的字符串操作代码,实现更清晰、更健壮的数据解析逻辑。虽然在简单的场景中可能显得“杀鸡用牛刀”,但在处理复杂格式文本时,它能显著提升开发效率和代码可维护性。