Swift 5.8+能否创建含可变组件的可复用Regex?如何实现?
在Swift 5.8+中创建带可变组件的可复用Regex(非NSRegularExpression)
可以实现,根据Swift版本不同有两种可靠方案,完全无需依赖NSRegularExpression:
方案1:使用RegexBuilder(Swift 5.9+推荐)
Swift 5.9引入的RegexComponentBuilder提供了类型安全的正则构建方式,天然支持将字符串变量与正则片段组合,还会自动处理变量中的正则特殊字符(如., *, ?等),避免手动转义的麻烦。
示例代码:
import RegexBuilder func makeKeywordRegex(keyword: String) -> Regex<Substring> { Regex { // 匹配keyword前的任意字符(非贪婪模式,避免过度匹配) OneOrMore(.any, .reluctant) // 直接插入可变关键字,自动转义特殊字符 keyword // 匹配keyword后的任意字符 OneOrMore(.any) } } // 使用示例 let targetRegex = makeKeywordRegex(keyword: "test.") let sampleText = "This is a test. string with special chars" if let matchResult = sampleText.firstMatch(of: targetRegex) { print("匹配结果:\(matchResult.output)") }
方案2:字符串插值转Regex(兼容Swift 5.8)
如果项目还停留在Swift 5.8,可以通过字符串拼接生成正则模式,再转换为Regex类型。注意必须手动转义关键字中的正则特殊字符,否则会导致正则语法错误。
示例代码:
func makeKeywordRegex(keyword: String) throws -> Regex<Substring> { // 转义关键字中的正则特殊字符 let escapedKeyword = NSRegularExpression.escapedPattern(for: keyword) // 拼接完整正则模式 let regexPattern = ".*\\(escapedKeyword).*" // 将字符串模式转为Regex类型 return try Regex(string: regexPattern) } // 使用示例 do { let targetRegex = try makeKeywordRegex(keyword: "test*") let sampleText = "This is test* case" if let matchResult = sampleText.firstMatch(of: targetRegex) { print("匹配结果:\(matchResult.output)") } } catch { print("正则构建失败:\(error.localizedDescription)") }
注意事项
- 正则字面量
/.../确实不支持字符串插值,因为其语法中的()用于定义捕获组,与Swift字符串插值的\(...)语法冲突,因此只能使用上述两种非字面量方式。 - 优先推荐
RegexBuilder方案,它的类型安全性更强,还能避免手动转义的疏漏。
内容的提问来源于stack exchange,提问作者marc-medley
相关产品推荐
相关产品推荐

