一些实用工具,可以更轻松地在 Swift 中使用带有捕获组的正则表达式。
假设我们有一个正则表达式 (\w+) (.*) (\w+)
,以及一个我们想要将表达式匹配项解包到的结构体
class Result {
var first = ""
var last = ""
var number = 0
}
我们可以匹配一个表达式并像这样捕获结果
let pattern = try! NSRegularExpression(pattern: "(\\w+) (.*) (\\w+)", options: [])
var result = Result()
if pattern.firstMatch(in: "Sam 123 Deane", capturing: [\Result.first: 1, \Result.last: 3, \Result.number: 2], into: &result) {
// result now contains the captured parameters
}
请注意,这里的 Result
可以是一个类或一个结构体。
为了更简洁的映射,我们还可以使用命名捕获。
给定一个表达式
(?xi)
(?<first> \w+ ) ?(?-x: )
(?<number> .* ) ?(?-x: )
(?<last> \w+ )
和一个结果结构体
class Result: NSObject {
@objc var first = ""
@objc var last = ""
@objc var number = 0
}
我们可以匹配一个表达式并像这样捕获结果
var result = Result()
if namedCapturePattern.firstMatch(in: "Sam 123 Deane", capturing: &result) {
// result now contains the captured parameters
}
请注意,该实现依赖于键值支持来写入结果,因此 Result
实例必须是一个 Objective-C 类,需要捕获的任何命名属性也必须如此。
这是 Swift 反射的一个限制,目前仅支持读取值。
目前这只是一个草图。
需要扩展,添加返回匹配项列表的变体。
通过对 Swift 反射的一些改进,代码可以简化一些,并且可以消除对 Obj-C 继承的丑陋需求。