Shaula Blog

美丽的东西都是肤浅的

Swift RegexBuilder

在 Swift 5.7 中,苹果引入了全新的 RegexBuilder 框架,彻底改变了开发者处理正则表达式的范式。告别晦涩难懂的正则符号,拥抱类型安全、模块化且可读性强的 DSL(领域特定语言),本文将带你探索 RegexBuilder 的强大能力。

传统正则的痛点

传统正则表达式(如 /\d{3}-\d{4}/)存在两大问题:

  1. 可读性差:符号密集,难以理解和维护。
  2. 调试困难:细微错误(如转义字符遗漏)难以定位。
// 传统方式 - 匹配日期
let pattern = "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$"

RegexBuilder 核心优势

RegexBuilder 的引入解决了上述问题,带来了以下核心优势:

  1. 声明式语法:类似 SwiftUI 的 Builder 模式,语法更加自然和易于理解。
  2. 类型安全:编译时进行检查,减少运行时错误,提升代码的健壮性。
  3. 组合式设计:模块化组件可以自由拼装,便于构建复杂的正则表达式。
  4. 无缝集成:原生支持 Swift 字符串处理,提升开发效率。

核心组件详解

通过模块化构建块组合复杂表达式,RegexBuilder 的核心组件包括基础匹配、数量限定、捕获组等:

import RegexBuilder

// 1. 基础匹配
let digit = Regex { One(.digit) }  // 等价于 \d

// 2. 数量限定
let threeDigits = Regex { Repeat(count: 3) { .digit } }

// 3. 捕获组 (带类型转换)
let dateRegex = Regex {
  Capture { Repeat(4) { .digit } } // 年份
  "-"
  Capture { 
    ChoiceOf {  // 月份选择
      "0"..."1"
      "0"..."9"
    }
  }
  transform: { month in Int(month) } // 自动转为 Int
}

邮箱验证

在传统方式中,邮箱验证的正则表达式可能如下:

let emailPattern = #"^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$"#

使用 RegexBuilder 可以更清晰地实现:

let emailRegex = Regex {
  // 本地部分
  OneOrMore {
    CharacterClass(
      .word,              // 字母数字
      .anyOf("._%+-")     // 特殊字符
    )
  }
  "@"
  // 域名部分
  OneOrMore {
    CharacterClass(
      .word,
      .anyOf("-")
    )
  }
  "."
  Repeat(2...3) { .word } // 顶级域名
}

高级特性

RegexBuilder 还支持一些高级特性:

  1. 条件逻辑:动态调整匹配规则。

    Regex {
      if enableValidation {
        Capture { .digit }  // 条件性捕获
      }
    }
    
  2. 引用捕获组:匹配重复内容。

    Regex {
      Capture { OneOrMore(.word) }
      OneOrMore(.whitespace)
      Reference(.capture(1))  // 引用第一个捕获组
    }
    
  3. 自定义转换:自动类型处理。

    Regex {
      TryCapture {
        OneOrMore(.digit)
      } transform: {
        Int($0)  // 自动转为 Int? 类型
      }
    }
    

结语

正则表达式是一个强大的工具,但过度复杂的正则表达式可能导致代码难以维护。RegexBuilder 解决了正则表达式的可读性问题,同时也具有以下特性:

  • 编译时语法检查
  • 类型驱动数据转换
  • 可组合的匹配逻辑
  • 无缝衔接 Swift 生态

随着 Swift 6 对字符串处理能力的持续增强,RegexBuilder 正成为现代 Swift 开发中文本处理的首选工具。