比较的对象不是观感,而是同一请求在两份规则下的第一条命中结果。官方优先级是从上到下,顶部高于底部。差别只可能来自:列表顺序变化、某一类型的 payload 或出站变化、RULE-SET 所引用集合的内容变化、附加参数变化、逻辑括号变化,以及 UDP 是否导致继续向下匹配。比较时要固定请求的域名、网络类型和入站条件,只允许规则侧成为变量。
适用条件
适用于手头有更新前和更新后两份 rules,或者能确定只更新了 rule-providers 所提供的集合而 rules 行未改。请求样本要具体,至少包含完整域名;若涉及地址类规则,还需要理解文档中 DNS 解析与 no-resolve 的关系。比较目标是命中的规则类型加出站。若两份配置里 MATCH 之前的规则完全相同且集合内容也相同,却仍觉得有差别,应先怀疑 UDP 无支持而继续向下匹配,而不是假设存在本页未写的隐藏规则。
列出更新前后必须对齐的字段
步骤一:把两次配置的 rules 按行号抄成两列,每一行只保留类型、payload、出站和附加参数。类型要写官方全称,例如 DOMAIN、DOMAIN-SUFFIX、GEOSITE、IP-CIDR、GEOIP、RULE-SET、AND、OR、NOT、SUB-RULE、MATCH。步骤二:标出所有 RULE-SET。它们引用规则集合,需配置 rule-providers。若更新前后这一行的提供者名称与出站不变,差别可能在集合内部,比较时要单独注明“列表未变、集合变”。步骤三:标出所有带 no-resolve 或 src 的目标 IP 规则。前者跳过 DNS 解析,但若更早匹配已触发解析,则依旧会匹配;后者把目标 IP 匹配转为来源 IP 匹配。步骤四:标出逻辑规则的括号。文档要求注意括号,payload 为规则类型和其他 payload。括号增减本身就是一种需要比较的差别。
判断依据:只有类型、payload、出站、附加参数、括号、集合内容这六类变化,才会改变命中策略。单纯调整无关进程规则,只要样本网站不会触发 PROCESS-NAME 或 PROCESS-PATH,不应计入该网站的差别。
用同一请求走两遍匹配
固定一个网站域名,按官方语义分别走更新前和更新后的列表。先试 DOMAIN 完整匹配。再试 DOMAIN-SUFFIX:以 google.com 为例,它匹配 www.google.com、mail.google.com 和 google.com,但不匹配 content-google.com。再试关键字、通配符和正则。通配符仅支持 * 与 ?,且与配置文件其他地方的 Clash 格式通配符不相同。然后试 GEOSITE 与 RULE-SET。再试 IP 类与 GEOIP。端口、入站、进程、UID、NETWORK、DSCP 仅在样本确实具备这些条件时才比较。两边都未提前命中则比较 MATCH,它匹配所有请求、无需条件。
把两次的“第一条命中”写成同一格式:规则类型、匹配到的 payload、出站。若类型相同而出站不同,差别在该行被改写。若类型不同,差别在更高优先级插入或删除。若两次都落在同一 RULE-SET 行但出站不同,差别在集合内部或该行出站字段。若两次类型与出站都相同,但实际一个走代理一个走直连,再比较 UDP:请求为 udp 且节点没有 udp 支持时会继续向下匹配,这会造成规则看起来一样、命中策略却不同的差别。
失败时下一步
若两列规则对不上行:先对齐 MATCH 的位置,因为终点移动会改变所有未命中前面规则的请求。若对得上但网站仍无法解释:用后缀规则的反例检查是否误把关键字当成后缀。若怀疑集合:确认 RULE-SET 名称仍指向同一 rule-providers。若怀疑地址类:比较更新前后是否新增了会触发 DNS 的 IP 规则,以及 no-resolve、src 是否出现或消失。逻辑规则则只核对括号与 AND、OR、NOT 是否被替换。完成上述对照仍无差别时,停止扩大比较范围,回到该样本是否其实命中了入站或进程类规则。