如何用Swift RegexBuilder将ISO8601日期字符串转为Date?
问题
我知道通常可以使用带.withFullDate选项的ISO8601DateFormatter,将“yyyy-MM-dd”格式(仅日期的ISO8601格式,不含时间及时区)的字符串转换为Swift的Date类型,代码如下:
let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withFullDate] let date = formatter.date(from: "2023-10-21")
但我想了解是否可以借助Swift新的RegexBuilder的Capture和Transform实现该功能?似乎.date(...)方法需要指定locale,但我不关心区域设置,仅需将日期字符串转为Date类型。请问能否不编写字面量Regex,利用RegexBuilder内置的日期格式化功能完成需求?
回答
可以利用RegexBuilder的内置日期匹配能力结合Transform来实现,不需要手写正则字面量。关键是通过Locale(identifier: "en_US_POSIX")来规避区域设置的影响——这个locale是固定的,不会随系统区域变化,正好符合你不关心区域设置的需求。
方法一:使用ISO8601内置匹配器
直接用RegexBuilder提供的.iso8601(.date)规则匹配纯日期格式,代码示例:
import RegexBuilder import Foundation let dateRegex = Regex { Capture { Date(.iso8601(.date)) } transform: { match in match.date } } if let date = try? dateRegex.firstMatch(in: "2023-10-21")?.output { print(date) // 输出对应的Date实例 }
这里的Date(.iso8601(.date))是专门匹配ISO8601纯日期的内置匹配器,底层已经封装了正则逻辑,无需手动编写。指定固定locale是因为匹配器默认会用系统当前locale,而en_US_POSIX能保证匹配逻辑稳定,不受系统区域影响。
方法二:显式指定日期格式
如果需要更明确地限定格式,也可以直接指定yyyy-MM-dd格式,结合固定locale:
import RegexBuilder import Foundation let dateRegex = Regex { Capture { Date(format: "yyyy-MM-dd", locale: Locale(identifier: "en_US_POSIX")) } transform: { match in match.date } } if let date = try? dateRegex.firstMatch(in: "2023-10-21")?.output { print(date) // 输出对应的Date实例 }
这两种方式都不需要手写正则字面量,完全依赖RegexBuilder的内置功能就能完成字符串到Date的转换。
内容的提问来源于stack exchange,提问作者hvkale

