在 iOS 平台上,Surge、Quantumult X(圈 X)、Loon 是三款最主流的高级代理客户端。它们各自拥有强大的规则分流能力,但规则格式互不兼容——你在 Surge 上精心调教的数百条分流规则,直接导入 Quantumult X 会报错;Loon 的策略组语法和 Surge 的又不一样。
更头疼的是:网上分享的规则仓库往往只提供某一种客户端的格式。你看到一套完美的 Netflix 分流规则,结果它是 Surge 格式的,而你用的是 Loon。
本文将系统解决这个问题:从四款工具的规则语法差异入手,提供完整的映射表和转换方案,让你无论用哪款客户端,都能复用同一套规则体系。
一、为什么需要规则转换?
1.1 四款 iOS 代理工具的定位差异
| 工具 | 定位 | 规则格式 | 价格 | 学习曲线 |
|---|---|---|---|---|
| Surge | 专业网络调试工具箱 | INI 风格,最复杂 | $49.99 起 | ⭐⭐⭐⭐⭐ |
| Quantumult X | 轻量代理 + 轻量调试 | 自定义格式 | 49.99 终身 | ⭐⭐⭐ |
| Loon | 介于 Surge 和 QX 之间 | 类 Surge INI 风格 | 39.99 终身 | ⭐⭐⭐⭐ |
| Shadowrocket | 入门级代理工具 | 类 Surge 格式 | $2.99 一次性 | ⭐⭐ |
1.2 规则不兼容的根源
虽然四款工具都支持”基于域名/IP分流”这个核心概念,但它们在以下方面存在差异:
- 关键字命名:同样是”域名后缀匹配”,Surge 叫
DOMAIN-SUFFIX,QX 叫host-suffix,Loon 和 Shadowrocket 叫DOMAIN-SUFFIX(但大小写规则不同) - 出站动作命名:Surge 用
Proxy,QX 用PROXY,Shadowrocket 要求全大写PROXY - 策略组语法:Surge 用
policy-group,QX 用[policy],Loon 用[Proxy Group] - 配置文件结构:Surge 是 INI 格式,QX 是自定义分段格式,Loon 是类 INI 但段名不同
- 高级特性:Surge 的脚本/MITM、QX 的 rewrite、Loon 的 plugin 都是各自独有,无法跨客户端转换
1.3 什么时候需要转换?
| 场景 | 需要转换的内容 | 难度 |
|---|---|---|
| 从网上下载的规则只支持某一种客户端 | 规则集格式 | 简单 |
| 从 Surge 迁移到 QX/Loon | 全部配置 | 中等 |
| 多客户端同时使用(iPhone 用 Surge,iPad 用 QX) | 规则 + 策略组 | 中等 |
| 共享规则给朋友(对方用不同客户端) | 规则集格式 | 简单 |
| 机场订阅只提供 Clash 格式 | 订阅转换 | 需要 Sub-Store |
二、四客户端规则语法全景对比
2.1 配置文件结构对比
Surge 配置结构(INI 风格):
[General]bypass-system = trueskip-proxy = 127.0.0.1, 192.168.0.0/16, 10.0.0.0/8dns-server = 223.5.5.5, 119.29.29.29
[Proxy]Direct = directReject = rejectHK = https://hk.example.com:443, username, password
[Proxy Group]Proxy = select, HK, US, JPAuto = url-test, HK, US, JP, url=http://www.gstatic.com/generate_204, interval=300
[Rule]DOMAIN-SUFFIX,google.com,ProxyDOMAIN-KEYWORD,facebook,ProxyGEOIP,CN,DIRECTFINAL,ProxyQuantumult X 配置结构(自定义分段):
[general]server_check_url=http://www.gstatic.com/generate_204resource_parser_url=https://raw.githubusercontent.com/KOP-XIAO/QuantumultX/master/Scripts/resource-parser.js
[policy]available=HK, server-check-tag=Check, img-path=available.pngstatic=Proxy, HK, US, JPround-robin=Balance, HK, US, JP
[server_remote]https://example.com/sub, tag=机场A
[filter_remote]https://raw.githubusercontent.com/.../proxy.list, tag=代理, force-policy=Proxyhttps://raw.githubusercontent.com/.../direct.list, tag=直连
[rewrite_remote]https://raw.githubusercontent.com/.../rewrite.conf, tag=重写Loon 配置结构(类 INI 但段名不同):
[General]skip-proxy = 127.0.0.1, 192.168.0.0/16dns-server = 223.5.5.5, 119.29.29.29
[Proxy]Direct = DIRECTReject = REJECTHK = hysteria2, hk.example.com, 443, password=xxx
[Proxy Group]Proxy = select, HK, US, JPAuto = url-test, HK, US, JP, url=http://www.gstatic.com/generate_204, interval=300
[Remote Rule]https://raw.githubusercontent.com/.../proxy.list, policy=Proxyhttps://raw.githubusercontent.com/.../direct.list, policy=DIRECT
[Rule]DOMAIN-SUFFIX,google.com,ProxyDOMAIN-KEYWORD,facebook,ProxyGEOIP,CN,DIRECTFINAL,ProxyShadowrocket 配置结构(类 Surge 但更简):
[General]bypass-system = truedns-server = 223.5.5.5, 119.29.29.29
[Proxy]Direct = DIRECTReject = REJECTHK = https, hk.example.com, 443, username, password
[Proxy Group]Proxy = select, HK, US, JP
[Rule]DOMAIN-SUFFIX,google.com,PROXYDOMAIN-KEYWORD,facebook,PROXYGEOIP,CN,DIRECTFINAL,PROXY2.2 核心规则元素映射表
这是最关键的转换参考——同一个匹配规则在四款客户端中的不同写法:
| 规则类型 | Surge | Quantumult X | Loon | Shadowrocket | 说明 |
|---|---|---|---|---|---|
| 域名后缀匹配 | DOMAIN-SUFFIX,google.com,Proxy | host-suffix,google.com,Proxy | DOMAIN-SUFFIX,google.com,Proxy | DOMAIN-SUFFIX,google.com,PROXY | 匹配域名及所有子域名 |
| 完整域名匹配 | DOMAIN,www.apple.com,Direct | host,www.apple.com,Direct | DOMAIN,www.apple.com,Direct | DOMAIN,www.apple.com,DIRECT | 精确匹配完整域名 |
| 域名关键字 | DOMAIN-KEYWORD,netflix,Proxy | host-keyword,netflix,Proxy | DOMAIN-KEYWORD,netflix,Proxy | DOMAIN-KEYWORD,netflix,PROXY | 域名包含关键字即匹配 |
| IP-CIDR | IP-CIDR,192.168.1.0/24,DIRECT | ip-cidr,192.168.1.0/24,DIRECT | IP-CIDR,192.168.1.0/24,DIRECT | IP-CIDR,192.168.1.0/24,DIRECT | IP 段匹配 |
| IP-CIDR6 | IP-CIDR6,fe80::/10,DIRECT | ip6-cidr,fe80::/10,DIRECT | IP-CIDR6,fe80::/10,DIRECT | IP-CIDR6,fe80::/10,DIRECT | IPv6 段匹配 |
| GeoIP | GEOIP,CN,DIRECT | geoip,cn,DIRECT | GEOIP,CN,DIRECT | GEOIP,CN,DIRECT | 基于国家代码匹配 |
| 用户代理 | USER-AGENT,Netflix*,Proxy | user-agent,Netflix*,Proxy | USER-AGENT,Netflix*,Proxy | USER-AGENT,Netflix*,PROXY | 匹配 HTTP User-Agent |
| 进程名 (仅Surge) | PROCESS-NAME,Telegram,Proxy | ❌ 不支持 | PROCESS-NAME,Telegram,Proxy | ❌ 不支持 | 按进程名分流 |
| 最终规则 | FINAL,Proxy | final,Proxy | FINAL,Proxy | FINAL,PROXY | 兜底规则 |
| 规则集 | RULE-SET,SYSTEM,DIRECT | ❌ 使用 filter_remote | RULE-SET,https://...list,Proxy | RULE-SET,https://...list,PROXY | 引用外部规则集 |
2.3 出站动作命名对比
| 动作 | Surge | Quantumult X | Loon | Shadowrocket |
|---|---|---|---|---|
| 代理 | Proxy(策略组名) | PROXY(需大写) | Proxy(策略组名) | PROXY(必须大写) |
| 直连 | DIRECT | DIRECT | DIRECT | DIRECT |
| 拒绝 | REJECT | REJECT | REJECT | REJECT |
| 拒绝+丢弃 | REJECT-DROP | REJECT-DROP | REJECT-DROP | REJECT-DROP |
| 拒绝+图片 | REJECT-IMG | REJECT-IMG | REJECT-IMG | REJECT-IMG |
| 拒绝+空响应 | REJECT-NO-DROP | REJECT-NO-DROP | REJECT-NO-DROP | ❌ 不支持 |
⚠️ 大小写陷阱:Shadowrocket 的出站动作(
PROXY、DIRECT、REJECT)必须全大写。Surge 和 Loon 对策略组名大小写不敏感但约定首字母大写。QX 要求DIRECT和REJECT大写,但自定义策略组名可混合大小写。
三、Surge → Quantumult X 转换
3.1 手动转换步骤
从 Surge 迁移到 QX 是最常见的转换场景。核心步骤:
Step 1:规则语法替换
将 Surge 规则中的关键字替换为 QX 格式:
# Surge 原始规则DOMAIN-SUFFIX,google.com,ProxyDOMAIN-KEYWORD,netflix,ProxyIP-CIDR,10.0.0.0/8,DIRECT,no-resolveGEOIP,CN,DIRECTFINAL,Proxy
# 转换后 QX 规则host-suffix,google.com,Proxyhost-keyword,netflix,Proxyip-cidr,10.0.0.0/8,DIRECT,no-resolvegeoip,cn,DIRECTfinal,ProxyStep 2:策略组转换
Surge 的 [Proxy Group] 对应 QX 的 [policy]:
# Surge 策略组[Proxy Group]Proxy = select, HK, US, JPAuto = url-test, HK, US, JP, url=http://www.gstatic.com/generate_204, interval=300Fallback = fallback, HK, US, JP, url=http://www.gstatic.com/generate_204, interval=300
# 转换后 QX 策略组[policy]static=Proxy, HK, US, JPavailable=Auto, HK, US, JP, check-url=http://www.gstatic.com/generate_204, check-interval=300round-robin=Fallback, HK, US, JP策略组类型映射:
| Surge 类型 | QX 类型 | 说明 |
|---|---|---|
select | static | 手动选择 |
url-test | available | 自动测速选最快 |
fallback | round-robin | 轮询(注意:QX 的 fallback 需要用 available + 重试逻辑模拟) |
load-balance | round-robin | 负载均衡 |
⚠️ 重要差异:Surge 的
fallback是”故障转移”(主节点失败才切备用),而 QX 的round-robin是”轮询”(依次使用)。如果你需要 Surge 的 fallback 行为,在 QX 中应使用available类型。
Step 3:MITM/Rewrite 转换
Surge 的 [MITM] 和 [Script] 在 QX 中对应 [mitm] 和 [rewrite]:
# Surge MITM[MITM]hostname = *.google.com, api.netflix.comca-passthrough = true
# QX mitm[mitm]hostname = *.google.com, api.netflix.com# Surge 脚本[Script]http-request ^https://api\.example\.com/script script-path=example.js, requires-body=true
# QX rewrite[rewrite_local]^https://api\.example\.com/script url script-request-header example.js3.2 注意事项
no-resolve参数:Surge 和 QX 都支持no-resolve参数(用于 IP 规则跳过 DNS 解析),但位置不同。Surge 放在规则末尾,QX 也放在末尾,语法一致USER-AGENT通配符:Surge 使用*通配符,QX 也支持*,但 QX 对正则表达式的支持更有限RULE-SET差异:Surge 使用RULE-SET引用本地或远程规则集,QX 使用[filter_remote]引用远程规则、[filter_local]引用本地规则PROCESS-NAME:QX 不支持进程名规则,如果你的 Surge 配置中有PROCESS-NAME规则,迁移到 QX 时需要删除或替换为域名规则
四、Surge → Loon 转换
4.1 为什么 Surge → Loon 相对简单?
Loon 的配置格式刻意设计为与 Surge 高度相似,降低迁移门槛。两者的 [General]、[Proxy]、[Proxy Group]、[Rule] 段名和语法几乎一致。
4.2 关键差异与转换
差异 1:节点协议语法
# Surge 节点(Shadowsocks)[Proxy]HK = custom, hk.example.com, 443, aes-128-gcm, password, https://raw.githubusercontent.com/.../SSEncrypt.module
# Loon 节点(Shadowsocks)[Proxy]HK = shadowsocks, hk.example.com, 443, aes-128-gcm, password# Surge 节点(VMess)[Proxy]US = vmess, us.example.com, 443, username=uuid, tls=true
# Loon 节点(VMess)[Proxy]US = vmess, us.example.com, 443, username=uuid, tls=true# Surge 节点(Hysteria2)[Proxy]JP = hysteria2, jp.example.com, 443, password=xxx, sni=jp.example.com
# Loon 节点(Hysteria2)[Proxy]JP = hysteria2, jp.example.com, 443, password=xxx, sni=jp.example.com差异 2:远程规则引用
# Surge 远程规则集[Rule]RULE-SET,https://raw.githubusercontent.com/.../proxy.list,Proxy
# Loon 远程规则[Remote Rule]https://raw.githubusercontent.com/.../proxy.list, policy=Proxy
# Loon 本地规则[Rule]DOMAIN-SUFFIX,google.com,Proxy差异 3:插件系统
Loon 有独特的 [Plugin] 概念,类似于将一组规则、重写、脚本打包成一个可复用的模块:
# Loon Plugin 示例[Plugin]https://raw.githubusercontent.com/.../BlockAA.plugin, tag=去广告https://raw.githubusercontent.com/.../Streaming.plugin, tag=流媒体分流Surge 没有等价的 Plugin 系统,最接近的是 [Rule] 中的 RULE-SET。
4.3 转换清单
| Surge 元素 | Loon 对应 | 转换难度 |
|---|---|---|
[General] | [General] | ⭐ 几乎相同 |
[Proxy] | [Proxy] | ⭐⭐ 协议关键字略有不同 |
[Proxy Group] | [Proxy Group] | ⭐ 语法一致 |
[Rule] 本地规则 | [Rule] | ⭐ 语法一致 |
[Rule] RULE-SET | [Remote Rule] | ⭐⭐ 需改格式 |
[MITM] | [MITM] | ⭐ 语法一致 |
[Script] | [Plugin] 或 [Rewrite] | ⭐⭐⭐ 需重新编写 |
[URL Rewrite] | [Rewrite] | ⭐⭐ 语法略有不同 |
五、Quantumult X / Loon → Surge 反向转换
5.1 QX → Surge
从 QX 迁移回 Surge 时,需要注意:
# QX 规则host-suffix,google.com,Proxyhost-keyword,netflix,Proxyip-cidr,10.0.0.0/8,DIRECTgeoip,cn,DIRECTfinal,Proxy
# 转换为 Surge 规则DOMAIN-SUFFIX,google.com,ProxyDOMAIN-KEYWORD,netflix,ProxyIP-CIDR,10.0.0.0/8,DIRECTGEOIP,CN,DIRECTFINAL,ProxyQX 策略组 → Surge 策略组:
# QX 策略组[policy]static=Proxy, HK, US, JPavailable=Auto, HK, US, JP, check-url=http://www.gstatic.com/generate_204, check-interval=300
# Surge 策略组[Proxy Group]Proxy = select, HK, US, JPAuto = url-test, HK, US, JP, url=http://www.gstatic.com/generate_204, interval=3005.2 Loon → Surge
由于 Loon 和 Surge 格式高度相似,反向转换主要是:
- 将
[Remote Rule]改回[Rule]中的RULE-SET - 将
[Plugin]拆解为[Rule]+[Rewrite]+[Script] - 检查协议关键字是否兼容
# Loon 远程规则[Remote Rule]https://raw.githubusercontent.com/.../proxy.list, policy=Proxy
# 转换为 Surge 规则[Rule]RULE-SET,https://raw.githubusercontent.com/.../proxy.list,Proxy六、策略组与分流规则转换注意事项
6.1 策略组嵌套差异
Surge 支持策略组嵌套(一个策略组引用另一个策略组),QX 和 Loon 也支持但语法不同:
# Surge 策略组嵌套[Proxy Group]Proxy = select, HK, US, JPStreaming = select, Proxy, DIRECTAll = select, Proxy, Streaming, DIRECT
# QX 策略组嵌套[policy]static=Proxy, HK, US, JPstatic=Streaming, Proxy, DIRECTstatic=All, Proxy, Streaming, DIRECT
# Loon 策略组嵌套(与 Surge 一致)[Proxy Group]Proxy = select, HK, US, JPStreaming = select, Proxy, DIRECTAll = select, Proxy, Streaming, DIRECT6.2 正则表达式差异
四款工具对正则表达式的支持程度不同:
| 特性 | Surge | QX | Loon | Shadowrocket |
|---|---|---|---|---|
| URL 重写正则 | ✅ PCRE | ✅ 有限 | ✅ PCRE | ✅ 有限 |
| 域名正则匹配 | ❌ 不支持 | ✅ host,regex,... | ❌ 不支持 | ❌ 不支持 |
| User-Agent 正则 | ✅ | ✅ | ✅ | ✅ |
| Rewrite 正则引擎 | PCRE | JavaScript | PCRE | PCRE |
⚠️ QX 的正则使用 JavaScript 引擎,与 Surge/Loon 的 PCRE 引擎在语法上有细微差异(如 lookahead/lookbehind 支持程度不同)。
6.3 规则优先级差异
| 客户端 | 规则匹配顺序 | 注意事项 |
|---|---|---|
| Surge | 从上到下,先匹配先生效 | FINAL 必须在最后 |
| QX | 从上到下,先匹配先生效 | final 必须在最后;filter_local 优先于 filter_remote |
| Loon | [Rule] > [Remote Rule] | 本地规则总是优先于远程规则 |
| Shadowrocket | 从上到下,先匹配先生效 | FINAL 必须在最后 |
⚠️ Loon 特殊行为:Loon 的
[Remote Rule]优先级低于[Rule]。如果你在[Rule]中有一条DOMAIN-SUFFIX,google.com,DIRECT,那么[Remote Rule]中任何匹配 google.com 的代理规则都不会生效。
七、Sub-Store:跨客户端规则统一管理方案
7.1 Sub-Store 是什么?
Sub-Store 是一款开源的高级订阅管理工具,支持 Quantumult X、Loon、Surge、Stash、Egern 和 Shadowrocket 六大客户端。它的核心价值是:一次配置,多端输出。
你只需要维护一份订阅源和规则集,Sub-Store 会自动转换为你需要的客户端格式。
7.2 部署方式
| 方式 | 适用场景 | 难度 |
|---|---|---|
| Loon/QX 内置运行 | iOS 本地运行,无需服务器 | ⭐ |
| Docker 部署 | 有 NAS/VPS 的用户 | ⭐⭐ |
| Cloudflare Workers | 免费 Serverless 部署 | ⭐⭐ |
| Vercel 部署 | 免费 Serverless 部署 | ⭐⭐ |
Loon 内置运行配置:
# 在 Loon 的 [Plugin] 中添加[Plugin]https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Loon.plugin, tag=Sub-Store, enabled=trueQX 内置运行配置:
# 在 QX 的 [filter_local] 中添加hostname *, sub.store
# 在 [general] 中添加;Sub-Store 前端地址sub_store_url = http://sub.store7.3 核心使用流程
┌─────────────────────────────────────┐│ Sub-Store 工作流 │├─────────────────────────────────────┤│ ││ 1. 添加订阅源 ││ └─ 机场订阅链接 / 自建节点 ││ ││ 2. 配置规则集 ││ ├─ 代理规则(Google/Netflix/...)││ ├─ 直连规则(国内域名/IP) ││ └─ 广告拦截规则 ││ ││ 3. 设置策略组 ││ ├─ 手动选择组 ││ ├─ 自动测速组 ││ └─ 故障转移组 ││ ││ 4. 生成输出 ││ ├─ Surge 格式 → Surge/Mac ││ ├─ QX 格式 → Quantumult X ││ ├─ Loon 格式 → Loon ││ └─ Shadowrocket 格式 → 小火箭 ││ ││ 5. 在客户端中订阅 Sub-Store 输出链接 ││ │└─────────────────────────────────────┘7.4 Sub-Store 规则集配置示例
在 Sub-Store 后台中,你可以为每个输出配置不同的规则组合:
{ "name": "我的Surge配置", "target": "Surge", "rules": [ { "type": "remote", "url": "https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Google/Google.list", "tag": "Google", "policy": "Proxy" }, { "type": "remote", "url": "https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Netflix/Netflix.list", "tag": "Netflix", "policy": "Streaming" }, { "type": "remote", "url": "https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/China/China.list", "tag": "China", "policy": "DIRECT" } ], "proxy_groups": [ { "name": "Proxy", "type": "select", "proxies": ["HK", "US", "JP"] }, { "name": "Streaming", "type": "select", "proxies": ["Proxy", "US", "JP"] }, { "name": "Auto", "type": "url-test", "proxies": ["HK", "US", "JP"], "url": "http://www.gstatic.com/generate_204", "interval": 300 } ]}7.5 Sub-Store 的优势
| 优势 | 说明 |
|---|---|
| 一次配置多端输出 | 维护一套规则,自动生成 Surge/QX/Loon/Shadowrocket 格式 |
| 规则集远程同步 | 规则更新后所有客户端自动同步 |
| 策略组自动生成 | 根据订阅节点自动创建策略组 |
| 节点筛选与重命名 | 按关键词筛选节点,自动重命名 |
| 同步到 Gist | 配置备份到 GitHub Gist,跨设备同步 |
八、在线转换工具
除了 Sub-Store,还有一些在线工具可以实现快速格式转换:
8.1 subconverter(订阅转换器)
subconverter 是最老牌的开源订阅转换工具,支持 Clash/Surge/QX/Loon/Shadowrocket 等多种格式互转。
在线使用:
# 将 Clash 订阅转换为 Surge 格式https://sub.example.com/sub?target=surge&url=YOUR_SUBSCRIPTION_URL
# 将 Clash 订阅转换为 QX 格式https://sub.example.com/sub?target=quanx&url=YOUR_SUBSCRIPTION_URL
# 将 Clash 订阅转换为 Loon 格式https://sub.example.com/sub?target=loon&url=YOUR_SUBSCRIPTION_URL常用公共前端:
| 前端 | 地址 | 说明 |
|---|---|---|
| sub.tsutsu.one | https://sub.tsutsu.one | 稳定,支持多格式 |
| acl45c | https://acl45c.vercel.app | Vercel 部署 |
| 自建 | Docker 部署 subconverter | 最安全,推荐 |
⚠️ 安全提示:公共 subconverter 前端会获取你的订阅链接并解析,存在订阅泄露风险。建议自建或使用 Sub-Store 替代。
8.2 规则集格式转换
如果只需要转换规则集(不含节点信息),可以使用以下方法:
方法 1:手动批量替换(VS Code)
在 VS Code 中打开规则文件,使用正则替换:
# 将 QX 格式转换为 Surge 格式查找: ^host-suffix,替换: DOMAIN-SUFFIX,
查找: ^host-keyword,替换: DOMAIN-KEYWORD,
查找: ^host,替换: DOMAIN,
查找: ^ip-cidr,替换: IP-CIDR,
查找: ^geoip,替换: GEOIP,
查找: ^final,替换: FINAL,方法 2:Python 转换脚本
#!/usr/bin/env python3"""规则格式转换脚本:QX → Surge/Loon/Shadowrocket"""
import reimport sys
# QX → Surge 关键字映射MAPPING = { r'^host-suffix,': 'DOMAIN-SUFFIX,', r'^host-keyword,': 'DOMAIN-KEYWORD,', r'^host,': 'DOMAIN,', r'^ip-cidr,': 'IP-CIDR,', r'^ip6-cidr,': 'IP-CIDR6,', r'^geoip,': 'GEOIP,', r'^user-agent,': 'USER-AGENT,', r'^final,': 'FINAL,',}
def convert_qx_to_surge(input_file, output_file, action_case='upper'): """将 QX 规则转换为 Surge 格式
action_case: 'upper' 将动作转为大写(Shadowrocket 用),'keep' 保持原样(Surge 用) """ with open(input_file, 'r', encoding='utf-8') as f: content = f.read()
for qx_pattern, surge_replacement in MAPPING.items(): content = re.sub(qx_pattern, surge_replacement, content, flags=re.MULTILINE)
if action_case == 'upper': # Shadowrocket 需要大写出站动作 for action in ['proxy', 'direct', 'reject']: content = re.sub( rf',{action}\b', f',{action.upper()}', content, flags=re.IGNORECASE )
with open(output_file, 'w', encoding='utf-8') as f: f.write(content)
print(f"转换完成: {input_file} → {output_file}")
if __name__ == '__main__': if len(sys.argv) < 3: print("用法: python convert_rules.py <input.list> <output.list> [upper|keep]") sys.exit(1)
case = sys.argv[3] if len(sys.argv) > 3 else 'keep' convert_qx_to_surge(sys.argv[1], sys.argv[2], case)九、常见转换陷阱与 Debug 方法
9.1 陷阱清单
| # | 陷阱 | 影响 | 解决方案 |
|---|---|---|---|
| 1 | 大小写不一致 | Shadowrocket 动作必须全大写,QX 部分大小写敏感 | 统一转换为对应客户端要求的大小写 |
| 2 | 逗号后空格 | 部分客户端对逗号后空格敏感 | 统一不加空格:DOMAIN-SUFFIX,google.com,Proxy |
| 3 | 注释格式不同 | Surge 用 #,QX 部分场景用 ; 或 // | 转换时检查注释符号 |
| 4 | 规则集 URL 格式 | Surge/Loon 的远程规则引用格式不同 | 按目标客户端格式重写 |
| 5 | 策略组引用顺序 | 策略组必须在被引用之前定义 | 检查定义顺序,被引用的组放前面 |
| 6 | 正则引擎差异 | QX 用 JS 引擎,Surge 用 PCRE | 测试正则是否在目标客户端中正常工作 |
| 7 | no-resolve 参数丢失 | IP 规则未加 no-resolve 导致 DNS 泄露 | 转换时检查所有 IP-CIDR 规则 |
| 8 | PROCESS-NAME 不兼容 | QX/Shadowrocket 不支持进程名规则 | 删除或替换为域名规则 |
| 9 | USER-AGENT 通配符 | 各客户端对 * 和 ? 的支持不同 | 测试 User-Agent 规则是否正常匹配 |
| 10 | FINAL 规则缺失 | 忘记添加兜底规则导致未匹配流量直接断开 | 确保转换后末尾有 FINAL/final 规则 |
9.2 Debug 方法
方法 1:逐步排查法
当转换后规则不生效时,按以下步骤排查:
Step 1: 检查配置是否被客户端正确加载 └─ 在客户端中查看规则列表是否完整
Step 2: 检查规则格式是否正确 └─ 逐行检查关键字、大小写、逗号格式
Step 3: 检查规则顺序 └─ 确保高优先级规则在前,FINAL 在最后
Step 4: 检查策略组是否正确定义 └─ 确保规则中引用的策略组名与定义一致
Step 5: 使用客户端的调试工具 ├─ Surge: Dashboard → 请求查看器 ├─ QX: 网络活动 → 请求详情 ├─ Loon: 日志 → 测试请求 └─ Shadowrocket: 当前连接 → 查看匹配规则方法 2:在线规则测试
在 browserling.com 或本地使用正则测试工具验证规则匹配逻辑。
方法 3:最小化测试
创建一个只包含 3-5 条规则的测试配置,验证基本功能后再逐步添加完整规则集。
9.3 常见错误对照表
| 错误现象 | 可能原因 | 修复方法 |
|---|---|---|
| 导入后所有流量走直连 | FINAL 规则指向了 DIRECT 或策略组名为空 | 检查 FINAL 规则和策略组名 |
| 导入后所有流量走代理 | 直连规则未正确转换或缺失 | 检查 GEOIP,CN,DIRECT 等直连规则 |
| 特定网站无法访问 | 规则匹配冲突或正则错误 | 用客户端调试工具查看该网站的匹配规则 |
| 部分规则不生效 | 大小写不一致或格式错误 | 逐行检查不生效的规则格式 |
| 策略组无法切换节点 | 策略组定义语法错误 | 检查策略组定义是否符合目标客户端语法 |
| 配置导入报错 | 配置文件结构不完整 | 检查必需的配置段是否存在 |
十、推荐规则集仓库
以下仓库提供多格式规则集,可直接引用或转换使用:
| 仓库 | 格式支持 | 说明 |
|---|---|---|
| blackmatrix7/ios_rule_script | Surge/QX/Loon/Shadowrocket | 最全的多格式规则集,按平台分类 |
| Hackl0us/SS-Rule-Snippet | Surge/QX/Loon | 经典规则集,定期更新 |
| Loon0x00/Loon-Plugin | Loon 专属 | Loon 官方插件仓库 |
| chavyleung/scripts | QX/Surge/Loon | 签到脚本 + 规则 |
| NobyDa/Script | QX/Surge/Loon | 去广告 + 重写规则 |
推荐配置组合
日常使用(Surge):
[Rule]# 广告拦截RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Advertising/Advertising.list,REJECT
# AI 工具RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/OpenAI/OpenAI.list,ProxyRULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Anthropic/Anthropic.list,Proxy
# 流媒体RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Netflix/Netflix.list,StreamingRULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/YouTube/YouTube.list,Streaming
# 国外常用RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Google/Google.list,ProxyRULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/Telegram/Telegram.list,Proxy
# 国内直连RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Surge/China/China.list,DIRECT
# 兜底GEOIP,CN,DIRECTFINAL,Proxy日常使用(Quantumult X):
[filter_remote]# 广告拦截https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/QuantumultX/Advertising/Advertising.list, tag=广告拦截, force-policy=REJECT
# AI 工具https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/QuantumultX/OpenAI/OpenAI.list, tag=OpenAI, force-policy=Proxyhttps://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/QuantumultX/Anthropic/Anthropic.list, tag=Anthropic, force-policy=Proxy
# 流媒体https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/QuantumultX/Netflix/Netflix.list, tag=Netflix, force-policy=Streaminghttps://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/QuantumultX/YouTube/YouTube.list, tag=YouTube, force-policy=Streaming
# 国内直连https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/QuantumultX/China/China.list, tag=国内直连, force-policy=DIRECT日常使用(Loon):
[Remote Rule]https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Loon/Advertising/Advertising.list, policy=REJECT, tag=广告拦截https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Loon/OpenAI/OpenAI.list, policy=Proxy, tag=OpenAIhttps://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Loon/Netflix/Netflix.list, policy=Streaming, tag=Netflixhttps://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Loon/China/China.list, policy=DIRECT, tag=国内直连总结:选择适合你的方案
| 你的情况 | 推荐方案 |
|---|---|
| 只需要转换一次,从 Surge 迁到 QX/Loon | 手动转换 + 在线 subconverter |
| 多设备多客户端长期使用 | Sub-Store(最佳方案) |
| 只需要共享规则给朋友 | 手动转换或 Python 脚本 |
| 需要频繁更新规则集 | Sub-Store + GitHub Gist 同步 |
| 不想折腾,开箱即用 | 使用 blackmatrix7 仓库的对应格式规则集 |
核心建议:
- 优先使用 Sub-Store:如果你同时使用多款 iOS 代理工具,或者频繁切换客户端,Sub-Store 是唯一的一劳永逸方案
- 统一规则源:无论用哪种方案,始终从同一个规则仓库(如 blackmatrix7)获取规则,避免格式混乱
- 转换后必须测试:每次转换后,用客户端的调试工具验证关键规则是否正常匹配
- 保留原始配置备份:转换前务必备份原始配置文件,以便回滚
📌 本文基于 Surge 6 / Quantumult X 1.2.x / Loon 3.x / Shadowrocket 2.2.x 版本编写。各工具持续更新,具体语法请以最新版官方文档为准。