6

谷歌分析不再允许在其过滤器中进行负前瞻。事实证明,要创建仅包含我希望包含的链接的自定义报告非常困难。

如果启用它,包含负前瞻的正则表达式将起作用:

test.com(\/\??index\_(.*)\.php\??(.*)|\/\?(.*)|\/|)+(\s)*(?!.)

这匹配:

test.com
test.com/
test.com/index_fb2.php
test.com/index_fb2.php?ref=23
test.com/index_fb2.php?ref=23&e=35
test.com/?ref=23 
test.com/?ref=23&e=35

并且不匹配(应该如此):

test.com/ambassadors
test.com/admin/?signup=true 
test.com/randomtext/

我正在寻找如何调整我的正则表达式以仍然保持相同的匹配但不使用负前瞻。

谢谢!

4

2 回答 2

4

Google Analytics 似乎不支持单行和多行模式,这对我来说很有意义。URL 不能包含换行符,因此如果点与它们不匹配并不重要,并且除了整个字符串的开头和结尾之外,永远不需要^and匹配任何地方。$

这意味着(?!.)您的正则表达式中的 完全等同于$,它仅在字符串的最后匹配(例如\z,在支持它的风格中)。由于这是您的正则表达式中唯一的前瞻,您不应该遇到这个问题;你应该一直在使用$

但是,您的正则表达式还有其他问题,主要是由于过度依赖(.*). 例如,它匹配这些字符串:

test.com/?^#(%)!*%supercalifragilisticexpialidocious
test.com/index_ecky-ecky-ecky-ecky-PTANG!-vroop-boing_rowr.php (ni! shh!)

...我很确定你不想要。:P

试试这个正则表达式:

test\.com(?:/(?:index_\w+\.php)?(?:\?ref=\d+(?:&e=\d+)?)?)?\s*$

或更易读:

test\.com
(?:
  /
  (?:index_\w+\.php)?
  (?:
    \?ref=\d+
    (?:
      &e=\d+
    )?
  )?
)?
\s*$

出于说明目的,我对(例如)可以存在哪些参数、它们将出现的顺序以及它们的值可以是什么进行了很多简化假设。我也想知道是否真的有必要匹配域(test.com)。我没有使用 Google Analytics 的经验,但比赛不应该在域之后立即开始(并锚定)吗?你真的必须在最后允许空格吗?在我看来,正则表达式应该更像这样:

^/(?:index_\w+\.php)?(?:\?ref=\d+(?:&e=\d+)?)?$
于 2012-11-13T16:04:52.890 回答
1

首先,我认为您的正则表达式需要一些修复。让我们看看你有什么:

test.com(\/\??index_.*.php\??(.*)|\/\?(.*)|\/|)+(\s)*(?!.)

第二种选择已经处理了您?在开头使用 optional 的情况:index...

test.com(\/index_.*.php\??(.*)|\/\?(.*)|\/|)+(\s)*(?!.)

现在你可能只希望第一个(.*)被允许,如果之前确实有一个文字?。否则你会匹配test.com/index_fb2.phpanystringhereandyouprobablydon'twantthat。所以移动相应的可选标记:

test.com(\/index_.*.php(\?(.*))?|\/\?(.*)|\/|)+(\s)*(?!.)

现在.*尽可能多地消耗任何角色。此外,.前面的php消耗任何字符。这意味着您将同时允许test.com/index_fb2phptest.com/index_fb2.html?someparam=php。让我们把它变成文字.并且只允许非问号字符:

test.com(\/index_[^?]*\.php(\?(.*))?|\/\?(.*)|\/|)+(\s)*(?!.)

现在第一个、第二个和第三个选项可以合并为一个,如果我们也将文件名设为可选:

test.com(\/(index_[^?]*\.php)?(\?(.*))?|)+(\s)*(?!.)

最后,+可以删除,因为(.*)内部已经可以处理所有可能的重复。也(something|)(something)?

test.com(\/(index_[^?]*\.php)?(\?(.*))?)?(\s)*(?!.)

看到您的输入示例,这似乎更接近您实际想要匹配的内容。

然后回答你的问题。什么(?!.)取决于您是否使用singleline模式。如果你这样做了,它就断言你已经到达了字符串的末尾。在这种情况下,您可以简单地将其替换为\Z,它始终匹配字符串的结尾。如果你不这样做,那么它断言你已经到了一行的末尾。在这种情况下,您可以使用$,但您还需要使用多行模式,以便也$匹配行尾。

因此,如果您使用singleline模式(这可能意味着每个字符串只有一个 URL),请使用以下命令:

test.com(\/(index_[^?]*\.php)?(\?(.*))?)?(\s)*\Z

如果您不使用singleline模式(这可能意味着您可以在自己的行中有多个 URL),您还应该使用multiline模式和这种锚点:

test.com(\/(index_[^?]*\.php)?(\?(.*))?)?(\s)*$
于 2012-11-13T13:45:11.303 回答