Swift正则类型转换错误:如何适配任意子串匹配的Regex实例?
Swift自定义正则类的类型不匹配问题解决
问题描述
开发Swift类用于正则模式匹配时,初始化实例遇到Regex类型转换错误。
自定义类代码
import Foundation class Challenge { let title: String let description: String let regex: Regex<AnyRegexOutput> var isComplete: Bool init(title: String, description: String, regex: Regex<AnyRegexOutput>, isComplete: Bool = false) { self.title = title self.description = description self.regex = regex self.isComplete = isComplete } }
实例创建代码
var dailyChallenges = [ Challenge(title: "Update Title", description: "set a new website title", regex: /<title>(?!webview<\/title>)(.*?)<\/title>/), Challenge(title: "Add Image", description: "add an image with a source URL", regex: /<img(\s.*\s|\s)(src="http.+?")/), ]
错误提示
Cannot convert value of type 'Regex<(Substring, Substring)>' to expected argument type 'Regex<AnyRegexOutput>' Arguments to generic parameter 'Output' ('(Substring, Substring)' and 'AnyRegexOutput') are expected to be equal
以及:
Cannot convert value of type 'Regex<(Substring, Substring, Substring)>' to expected argument type 'Regex<AnyRegexOutput>' Arguments to generic parameter 'Output' ('(Substring, Substring, Substring)' and 'AnyRegexOutput') are expected to be equal
需求
修改类以支持任意数量子串匹配的正则模式,解决类型转换问题。
解决方案
方法1:转换Regex为统一类型
Swift字面量正则会根据捕获组数量生成对应Output类型的Regex,直接通过Regex<AnyRegexOutput>构造器转换传入的正则即可,无需修改原类:
var dailyChallenges = [ Challenge(title: "Update Title", description: "set a new website title", regex: Regex<AnyRegexOutput>(/<title>(?!webview<\/title>)(.*?)<\/title>/)), Challenge(title: "Add Image", description: "add an image with a source URL", regex: Regex<AnyRegexOutput>(/<img(\s.*\s|\s)(src="http.+?")/)), ]
方法2:泛型化Challenge类
将类改为泛型,兼容不同Output类型的Regex:
import Foundation class Challenge<Output> { let title: String let description: String let regex: Regex<Output> var isComplete: Bool init(title: String, description: String, regex: Regex<Output>, isComplete: Bool = false) { self.title = title self.description = description self.regex = regex self.isComplete = isComplete } }
创建实例时编译器会自动推断泛型类型,若需统一数组类型,可使用[Any],但此方案会增加后续类型处理的复杂度。
方法3:使用RegexComponent协议
利用Swift 5.7+支持的any RegexComponent作为属性类型,接受所有Regex类型:
import Foundation class Challenge { let title: String let description: String let regex: any RegexComponent var isComplete: Bool init(title: String, description: String, regex: any RegexComponent, isComplete: Bool = false) { self.title = title self.description = description self.regex = regex self.isComplete = isComplete } }
后续使用正则时,若需处理捕获组,需将其转换为Regex<AnyRegexOutput>再操作。
推荐方案
若仅需执行匹配操作、无需精确处理捕获组类型,方法1是最简洁低侵入的选择;若需更高灵活性,可选用方法3。
内容的提问来源于stack exchange,提问作者Azzam Rar
相关产品推荐
相关产品推荐

