In the 全球开发者大会视频,结果表明你可以这样做Capture
s/TryCapture
正则表达式生成器中的 s:
let regex = Regex {
// ...
TryCapture {
OneOrMore(.digit)
} transform: {
Int($0)
}
// ...
}
和输出Regex
将是类型安全的。这Regex
将输出一个Int
对于该组,而不是Substring
像平常一样。
但是,我想做的是改变整个输出类型Regex
,就像应用一个transform:
在结束时Regex
关闭。例如,要解析包含一个人的姓名、年龄和出生日期的行:
John (30) 1992-09-22
我想做这样的事情:
// this doesn't work and is just for illustration - there is no such Regex.init
let regex = Regex {
Capture(/\w+/)
" ("
TryCapture(/\d+/) { Int($0) }
") "
Capture(.iso8601Date(timeZone: .gmt))
} transform: { (_, name, age, dob) in
Person(name: String(name), age: age, dob: dob)
}
我希望regex
属于类型Regex<Person>
, 并不是Regex<(Substring, Substring, Int, Date)>
。那是,someString.wholeMatch(of: regex).output
将是一个字符串,而不是一个元组。
我基本上只是想减少元组的出现,因为我发现使用它们非常不方便,尤其是未命名的元组。自从RegexComponent
由无约束参数化RegexOutput
类型,并且有内置类型,其中RegexOutput
is Date
and Decimal
,使用正则表达式对任意类型执行此操作当然不是不可能的,对吗?
我的尝试是:
struct Person {
let name: String
let age: Int
let dob: Date
}
let line = "John (30) 1992-09-22"
let regex = Regex {
Capture {
Capture(/\w+/)
" ("
TryCapture(/\d+/) { Int($0) }
") "
Capture(.iso8601Date(timeZone: .gmt))
} transform: { (_, name, age, dob) in
Person(name: String(name), age: age, dob: dob)
}
}
line.wholeMatch(of: regex)
但这在运行时崩溃了,给出了以下消息:
无法将类型“Swift.Substring”(0x7ff865e3ead8)的值转换为“(Swift.Substring,Swift.Substring,Swift.Int,Foundation.Date)”(0x7ff863f2e660)。
我的另一个尝试使用CustomConsumingRegexComponent
显示在这个答案中,但这有一个很大的警告,即它不能正确回溯。
我怎样才能创建一个Regex
输出我自己的类型?