将多个正则表达式组合成一个/构建小正则表达式以匹配一组固定字符串

Combine multiple regexes into one / build small regex to match a set of fixed strings

情况:

我们创建了一个工具 Google Analytics Referrer Spam Killer,它会自动向 Google Analytics 添加过滤器以过滤掉垃圾邮件。

这些过滤器排除了来自某些垃圾域的流量。现在我们的列表中有 400 多个垃圾域。

为了删除垃圾邮件,我们添加了一个正则表达式(如 domain1.com|domain2.com|..)作为 Analytics 的过滤器,并告诉 Analytics 忽略所有匹配此过滤器的流量。

问题:

Google Analytics 对每个正则表达式有 255 个字符的限制(每个过滤器一个正则表达式)。因此,我们必须创建大量过滤器来添加所有 400 多个域(现在有 30 多个过滤器)。问题是,还有另一个限制。每天的写操作数。每个新过滤器都是 3 个以上的写入操作。

问题:

我想找到最短的正则表达式来精确匹配另一个正则表达式。

例如您需要匹配以下字符串:

`abc`, `abbc` and `aac`

您可以将它们与以下正则表达式匹配:/^abc|abbc|aac$//^a(b|bb|a)c$//^a(bb?|a)c$/ 等。

基本上我正在寻找一个与 /^abc|abbc|aac$/ 完全匹配但长度较短的表达式。

我找到了 multiregexp,但据我所知,它不会从我可以在 Analytics 中使用的另一个表达式创建新的正则表达式。

是否有可以优化正则表达式长度的工具?

我不知道用于组合/压缩/优化正则表达式的现有工具。可能有一个。也许通过用正则表达式构建一个有限状态机,然后从中生成一个正则表达式?

对于任意正则表达式的一般情况,您不需要解决问题。我认为创建紧凑的正则表达式来匹配任何给定的固定字符串集是一个更好的选择。

可能已经有一些现有代码可用于制作优化的正则表达式以匹配给定的一组固定字符串,同样是 IDK。

要自己动手,最简单的方法是对字符串进行排序并查找常见的前缀/后缀。 ((afoo|bbaz|c)bar.com)。在中间寻找常见的字符串并不容易。您可能想查看用于无损数据压缩的算法以查找冗余。

理想情况下,您希望发现可以使用 foo[a-d] 范围而不是 foo(a|b|c|d) 范围的情况,以及其他各种情况。

我找到了这个在 Linux 上编译的 C 工具:http://bisqwit.iki.fi/source/regexopt.html

超级简单:

$ ./regex-opt '123.123.123.123'
(123.){3}123

$ ./regex-opt 'abc|abbc|aac'
(aa|ab{1,2})c

$ ./regex-opt 'aback|abacus|abacuses|abaft|abaka|abakas|abalone|abalones|abamp'
aba(ck|ft|ka|lone|mp|(cu|ka|(cus|lon)e)s)

我无法运行 @sln 建议的工具。它看起来像是一个更短的正则表达式。