正则表达式匹配任何非子模式的东西

时间:2012-11-24 01:03:33

标签: regex varnish varnish-vcl

我的HTTP标头中有cookies,如下所示:

Set-Cookie: frontend=ovsu0p8khivgvp29samlago1q0; adminhtml=6df3s767g199d7mmk49dgni4t7; external_no_cache=1; ZDEDebuggerPresent=php,phtml,php3

我需要提取前端后面的26个字符串(例如ovsu0p8khivgvp29samlago1q0)。以下正则表达式与我匹配:

(?<=frontend=)(.*)(?=;)

但是,我使用的是Varnish Cache,只能使用正则表达式替换。因此,要提取该cookie值(26个字符frontend字符串),我需要匹配与该模式不匹配的所有字符(因此我可以用''替换它们。)

我做了很多谷歌搜索,但到目前为止已经空白了。我试过以下

  • 匹配与我想要的模式不匹配的字符:匹配随机字符的[^((?<=frontend=)[A-Za-z0-9]{26}(?=;))],包括我想要保留的字符

如果有人能指出我正确的方向,或者注意我可能出错的地方,我将不胜感激。

3 个答案:

答案 0 :(得分:2)

Set-Cookie响应标头在Varnish中有点神奇,因为后端往往会发送多个具有相同名称的标头。这是RFC禁止的,但实际上是这样做的。

如果您使用的是Varnish 3.0,您可以使用Header VMOD,它可以解析响应并提取您需要的内容:

https://github.com/varnish/libvmod-header

答案 1 :(得分:1)

使用正则表达式

^Set-Cookie:.*?\bfrontend=([^;]*)

并且前端“之后的”26字符串将在组1中(通常在替换字符串中称为$1

答案 2 :(得分:1)

您是否可以控制替换字符串?如果是这样,您可以使用Ωmega的答案,并在替换字符串中使用$1来写回frontend值。

否则,你可以使用它:

^Set-Cookie:.*(?!frontend=)|(?<=frontend=.{26}).*$

这将匹配从字符串开头到遇到frontend=的所有内容。或者它将匹配在其左边有frontend=正好26个字符并且直到字符串结尾的所有内容。如果这26个字符是可变长度的,那么它会变得非常复杂,因为只有.NET支持可变长度的lookbehinds。

关于你的上一个问题。我们来看看你的正则表达式:

[^((?<=frontend=)[A-Za-z0-9]{26}(?=;))]

好吧,首先你试图用你的模式包围的负面角色类[^...],并不是真的像这样工作。它仍然是一个字符类,因此它只匹配不在该类中的单个字符。但它变得更加复杂(我想知道为什么它会匹配)。首先,字符类应该由第一个 ]关闭。此字符类匹配任何非(?<=),字母或数字的内容。然后将{26}应用于此,因此我们尝试找到其中的26个字符。然后(?=;)断言这26个字符后跟;。现在应该不起作用。结束)实际应该抛出错误。最后的]只会被解释为文字]

有一些正则表达式允许嵌套字符类(Java确实如此)。在这种情况下,您只需要一个等同于[^a-zA-Z0-9(){}?<=;]的字符类。但据我所知,Varnish使用PCRE,而在PCRE中你的正则表达式应该不会编译。