一般来说, AdGuard 和 uBlock Origin 用的这种 Adblock Plus 风格的语法非常适合用于匹配 URL, 但是也会存在一些极其少见的情况必须要用到正则来匹配.

比如小红书的网页版, 主页使用参数来定位贴文频道位置:

  • https://www.xiaohongshu.com/explore?channel_id=homefeed_recommend

而具体的贴文则是:

  • https://www.xiaohongshu.com/explore/xxxxx?xsec_token=xxxxx

如果我们要清理小红书的贴文的参数, 一般就会写这样的规则:

1
||www.xiaohongshu.com/explore^$removeparam

但是这条规则不仅仅匹配到了贴文, 还匹配到了主页, 导致主页用来定位的参数会在刷新后命中规则, 然后被清理.

除非去详细指定要清理的参数键, 类似这样:

1
||www.xiaohongshu.com/explore^$removeparam=/^(p1|p2|p3)=/

这样能避开 channel_id 这样的主页参数被意外清理, 但是要最大限度清理参数非常繁琐(要显式指定每一个目标参数键), 当然也能排除特定的不需要清理(或者说不能)的参数键:

1
||www.xiaohongshu.com/explore^$removeparam=~channel_id

但问题又来了, 我们没办法确定 "不能" 清理的参数键在意外匹配到的页面上是否与实际我们要清理的贴文的 URL 有重合, 很可能一个参数在首页就是重要的, 但在贴文中就是无用的(大多数社媒的贴文页面参数基本都是无用的).


另外一个例子是新浪微博, 用户资料页是:

  • https://weibo.com/u/xxxxx?tabtype=feed

微博贴文页是:

  • https://weibo.com/123456/XrcXwXTWX?from=xxxxx

如果要清理微博贴文 URL 中的全部参数而直接用这条规则:

1
||weibo.com/*/*^$removeparam

很显然就会误伤到用户资料页的参数, 除非我们再写一条规则排除掉资料页:

1
@@||weibo.com/u^$removeparam

这种情况在用户侧实际上很多, 我们没办法观测黑盒里全部可以和不可以清理的参数, 只知道部分可以清理的和部分必要的参数. 这种匹配不精准的情况, 要么尽可能探明可以清理的参数精准指定, 要么尽量把规则的匹配范围限定在更加具体的 URL 上只保留部分必要的参数.

本来 "精准匹配" 就是写这类规则的首要考虑目标, 现在既然发现了容易被 "误伤" 的页面, 那就只能退而求其次选择更原始的正则匹配了:

  • 小红书贴文:

    1
    /https?:\/\/www\.xiaohongshu\.com\/explore\/[0-9a-z]+/$removeparam=~xsec_token
  • 微博贴文:

    1
    /https?:\/\/weibo\.com\/[0-9]+\/[0-9a-zA-Z]+/$removeparam

使用正则需要更加注意匹配范围的精确性, AdGuard 里的正则匹配性能相对一般过滤器规则表达式要差(虽然人也没办法非常直观地感受到).

How to create your own ad filters | AdGuard Knowledge Base - Regular expressions support

交叉发布