VCL regular expression cheat sheet
Last updated 2018-08-02
Fastly VCL uses a subset of Perl Compatible Regular Expression (PCRE) syntax. This is case sensitive and forward slashes don't need to be escaped. To disable case sensitivity, add (?i)
to the start of your expression.
Basic matching
1
req.url == "/phrase"
Matches only if req.url
is exactly /phrase
.
1
req.url ~ "phrase"
Matches phrase
anywhere.
Matching at the beginning or end of a string
1
req.http.host ~ "^www"
Matches if req.http.host
starts with www
.
1
req.url ~ "\.jpg$"
Matches if req.url
ends with .jpg
.
Multiple matches
1
req.url ~ "\.(png|jpg|css|js)$"
Matches if req.url
ends with either .png
, .jpg
, .css
, or .js
.
1
req.url ~ "\.php(\?.*)?$"
Matches if req.url
ends with .php
, .php?foo=bar
or .php?
, but not .phpa
.
You can also use req.url.ext
to find the file extension specified in a URL. For example, in the request www.example.com/1/hello.gif?foo=bar
, req.url.ext
will contain gif
.
1
req.url ~ "\.[abc]server$"
Matches if req.url
ends with .aserver
, .bserver
or .cserver
.
Matching wildcards
1
req.url ~ "jp.g$"
Matches if req.url
ends with jpeg
, jpag
, and jp0g
, but doesn't match if req.url
ends with jpg
. It also matches if any other character is between the jp
and the g
.
1
req.url ~ "jp.*g$"
Matches jp
followed by 0 or more random characters ending with the letter g
(jpeg
, jpg
, and jpeeeeg
all match).
Capturing matches
1
2
3
4
5
6
7
set req.http.Foo = "abbbccccc";
if (req.http.Foo ~ "^(a+)(b+)(c+)") {
set resp.http.match0 = re.group.0; # now equals 'abbbccccc'
set resp.http.match1 = re.group.1; # now equals 'a'
set resp.http.match2 = re.group.2; # now equals 'bbb'
set resp.http.match3 = re.group.3; # now equals 'cccccc'
}
The re.group.[0-9]
objects allow you to capture matches. The re.group.0
object evaluates to the entire matched string even if no capture groups have been supplied. You can use these objects to replace this example:
1
2
3
if (req.url ~ "(?i)\?.*some_query_arg=([^&]*)") {
set req.http.Thing-I-Want = regsub(req.url, "(?i)\?.*some_query_arg=([^&]*).*", "\1");
}
You can use re.group
to greatly simplify the previous example:
1
2
3
if (req.url ~ "(?i)\?.*some_query_arg=([^&]*)") {
set req.http.Thing-I-Want = re.group.1;
}
You could even get really fancy and do something like this:
1
set req.http.Thing-I-Want = if(req.url ~ "(?i)\?.*some_query_arg=([^&]*)", re.group.1, "");
Replacing content
1
set req.http.host = regsub(req.http.host, "^www\.","");
Removes a leading www.
from the host, if present.
1
set req.http.api-test = regsub(req.http.host, "^www\.","api.");
Sets the api-test
header to contain the host-header, but replaces a leading www.
with api.
:
1
2
3
4
5
6
Host: www.example.com ->
Host: www.example.com
api-test: api.example.com
Host: example.com ->
Host: example.com
api-test: example.com
1
set req.url = regsuball(req.url, "/+", "/");
Changes all occurrences of multiple slashes in the URL to a single slash. For example, //docs///intro.html
will be transformed to /docs/intro.html
.