适用条件与原有优先级的含义
整理 Clash(mihomo)的 rules 时,保留原有优先级是指:整理前后,任意请求从上到下遇到的第一条成立规则及其出站保持不变。官方定义规则按从上到下的顺序匹配,顶部高于底部。适用条件是:准备合并重复项、分组、改写类型或调整空白与注释,但并不打算改变谁先命中。若整理目的就是让某条更具体的规则提前,则不属于“保留”,应按改策略处理,不要与保序混为一谈。
MATCH 匹配所有请求、无需条件,它在列表中的相对位置属于优先级的一部分,整理时必须仍在全部有条件规则之后。UDP 在节点无 udp 支持时会继续向下匹配,因此“条件成立的行”与“真正收下 udp 的行”之间的相对顺序也要原样保留。
整理过程中保持相对顺序的操作
第一步,在改动前把现行列表看成有序序列,而不是按类型分组后的集合。可以给每一行编号:DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD、GEOSITE、IP-CIDR、GEOIP、RULE-SET、AND/OR/NOT、SUB-RULE、MATCH 不论类型如何穿插,编号顺序就是优先级。整理时允许把相邻且出站相同、且确认互不依赖解析副作用的行靠拢,但不允许跨过中间那些可能先命中的行。
第二步,合并或改写时以“相对位置不变”为约束。把若干 DOMAIN 收成一个 RULE-SET,等于用一个槽位替换原来多行:只有当这些行原本连续、中间没有其他类型、且集合内部不再插入新的更宽规则时,整体优先级才近似保留。若原来分散在列表不同高度,收成单个 RULE-SET 会改变与夹在中间的 GEOSITE、NOT、IP-CIDR 的先后,这是常见的破序操作,应放弃合并或拆成多个仍停在原高度的 RULE-SET。逻辑规则官方要求注意括号:把两条相邻规则改成 AND/OR 是在改变匹配集合,不是保序整理;保序时不要把先后两行折叠进一个 OR。
第三步,移动 MATCH、宽泛 NOT 和目标 IP 规则时单独核对。MATCH 上移会截断其后全部规则,等于改变优先级。NOT,((DOMAIN,baidu.com)) 范围很大,跨段移动会改变大量请求的第一条命中。目标 IP 类规则匹配时会触发 DNS,no-resolve 用于跳过;但更早的匹配一旦触发过解析,后面的 no-resolve 行依旧能匹配。整理时若把“会解析的 GEOIP/IP-CIDR”从某条 no-resolve 规则上方挪走,后面的 IP 规则可能不再看得到地址,策略随之变化。附加参数 src 把目标 IP 匹配转为来源 IP 匹配,移动这类行时比较对象仍是来源 IP,不要和普通目标 IP 行对调后还当保序。
第四步,涉及 UDP 续配的出站保持上下关系。官方例子是 ss 节点未写 udp: true 时 udp 继续向下。整理时不得把“无 udp 的出站规则”与“下方承接 udp 的 NETWORK,udp 或其他规则”对调;对调后,udp 要么被新的上层出站收走,要么失去原来的承接行。
核对是否保序与失败时下一步
判断依据:有条件规则相对 MATCH 的前后关系不变;任意两行若可能同时命中,它们的上下关系不变;会触发 DNS 的目标 IP 规则相对其后 no-resolve 行的前后关系不变;无 udp 支持的出站相对其下一条 udp 承接规则的前后关系不变。
若整理后部分域名改走其他出站,下一步用相交的那两行对照编号,看是否被分组时跨过了中间规则,恢复相对顺序而不是再加一条底部规则——底部优先级更低,补不回原优先级。若只有 IP 规则变化,下一步检查解析触发行是否被挪走,并把带 no-resolve 的行放回其原有的“已解析之后”位置。若只有 UDP 变化,下一步恢复无 udp 节点与承接行的原先后。SUB-RULE 括号或逻辑括号在整理中被改动时,下一步先按官方提醒把括号恢复原样,再谈分组美化。未改变相对顺序却结果不同,下一步核对是否误改了规则类型或出站名,那已超出保序范围。