SwiftLint自定义正则规则仅匹配单一场景,如何适配全部4种违规协议?
自定义SwiftLint规则:修复多成员协议检测问题
问题说明
我自定义了SwiftLint的protocol_single_responsibility_violation规则,用来检测违反单一职责原则的协议(即包含多个函数或变量的协议),但当前规则只能识别GroupedProtocol这一种违规场景,另外3类多成员协议无法被匹配,需要调整正则表达式实现全量检测。
原规则代码
custom_rules: protocol_single_responsibility_violation: name: "Protocol with more than one function and or variable" regex: '(protocol.*\{\n.*func.*\n.*func.*\})|(protocol.*\{\n.*var.*\n.*func.*\})|(protocol.*\{\n.*func.*\n.*var.*\})|(protocol.*\{\n.*var.*\n.*var.*\})' message: "If you would like to create a protocol with more than one function and or variable, then create separate protocols with one function or variable each, then combine them with a typealias. For example, typealias CombinedProtocol = FirstProtocol & SecondProtocol" severity: error
测试代码
protocol GroupedProtocol { // 仅能匹配此协议 func stuff() func stuff2() } protocol GroupedProtocol2 { var stuff: Int { get set } func stuff2() } protocol GroupedProtocol3 { var stuff: Int { get set } var stuff2: Int { get set } } protocol GroupedProtocol4 { func stuff2() var stuff: Int { get set } } protocol GroupedProtocol5 { func stuff() } class Decoy { }
问题根源
原正则表达式存在两个核心问题:
- 强制要求第二个成员的行直接包含闭合大括号,而实际代码中闭合大括号通常单独成行,导致匹配失败
- 默认未开启单行模式,
.无法匹配换行符,跨多行的内容无法被正确识别
修复方案
修改正则表达式,开启单行模式并调整匹配逻辑,确保能识别大括号内包含至少两个func或var成员的协议,不管成员顺序和排版格式:
修改后的完整规则代码
custom_rules: protocol_single_responsibility_violation: name: "Protocol with more than one function and or variable" regex: '(?s)protocol\s+\w+\s*\{\s*(?:.*?(func|var)\s+.*?\s*){2,}.*?\}' message: "If you would like to create a protocol with more than one function and or variable, then create separate protocols with one function or variable each, then combine them with a typealias. For example, typealias CombinedProtocol = FirstProtocol & SecondProtocol" severity: error
正则表达式解释
(?s):开启单行模式,让.可以匹配包括换行在内的所有字符protocol\s+\w+\s*\{\s*:匹配协议的声明开头,包含协议名、大括号及后续空白(?:.*?(func|var)\s+.*?\s*){2,}:匹配至少2个独立的func或var成员声明,非贪婪匹配避免过度占用内容.*?\}:匹配到协议的闭合大括号,确保匹配范围限定在单个协议内
效果验证
修改后的规则可以正确匹配GroupedProtocol、GroupedProtocol2、GroupedProtocol3、GroupedProtocol4这4种违规协议,仅包含单个成员的GroupedProtocol5不会被标记,完全符合检测需求。
内容的提问来源于stack exchange,提问作者ScottyBlades
相关产品推荐
相关产品推荐

