gkd 选择器调优:匹配顺序、正则优化与转义注意
选择器写对只是及格线,写得好还要跑得快、跨设备稳定。官方文档在「一些注意」小节里集中列了四件事,本页逐条消化。
一、匹配顺序是从右往左
这是选择器最反直觉的一条:FrameLayout > TextView 不是先找 FrameLayout 再找它的子 TextView,而是先找 TextView、再验证父级是否为 FrameLayout。
对写规则的指导意义:
- 把最具区分度的条件放在最右边,让引擎第一步就缩小范围;
- 右侧放
[id=...]或精确 text,左侧放宽松的类型约束,是标准写法; - 快照审查工具的路径视图会标明匹配顺序和查找方向,调试时可以直观看到引擎怎么走的。
二、正则的快速匹配优化
正则是选择器里最贵的操作。官方对满足特定格式的 matches / notMatches 做了自动优化——用内置的简单函数替代正则引擎:
[text~="(?is)abc.*"]→ 忽略大小写的 startsWith('abc');[text~="(?is).*abc.*"]→ 忽略大小写的 contains('abc');[text~="(?is).*abc"]→ 忽略大小写的 endsWith('abc');- 取反形式
!~=同样支持上述三种。
享受优化的前提:abc 部分不能含 \^$.?*|+()[]{} 这类正则特殊字符,且字符属于 ASCII(如 ikun 合格,ikun? 就不行)。如果只是想忽略大小写做个开头/包含/结尾判断,直接按这个格式写,别自己发明正则——更快也更稳。
三、跨平台的正则一致性
GKD 的选择器引擎同时跑在 Android 端和浏览器端(审查工具),两者用的正则实现不同(Kotlin Regex 与 Wasm 版正则)。官方明确提示:JVM 专用字符类、部分 Unicode 字符类和边界行为在两端可能不一致。实践建议:
- 写要发布给社区用的规则时,避开 JVM 专属正则语法;
- 两端各验证一遍再发布;
- 能用
*=^=$=简单操作符表达的,不用正则。
四、嵌套转义字符
字符串字面量支持 \ 转义(\\、\'、\n 等),但当选择器被包在 JSON5 订阅文件里时会出现两层转义:JSON 转义一层、选择器再转义一层。例如想匹配正则里的字面点号,订阅文件里要写成 \\. 的嵌套形态。这是新手写订阅文件最常见的报错来源——选择器在审查工具里单测正常,放进订阅文件就语法错误,八成是转义层数不对。
调优检查单
发布规则前过一遍:
- [ ] 最右端是不是最强条件?
- [ ] 有没有能用
*=/^=替代的正则? - [ ] 忽略大小写的判断是否用了
(?is)快速格式? - [ ] 字符串在订阅文件里转义正确吗?
- [ ] 加了
[visibleToUser=true]防止命中不可见节点吗? - [ ] 规则组上加了
fastQuery(简单属性时)、matchTime、actionMaximum限流吗?