VCL regular expression cheat sheet

  Last updated August 02, 2018

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

req.url == "/phrase"

Matches only if req.url is exactly /phrase.

req.url ~ "phrase"

Matches phrase anywhere.

Matching at the beginning or end of a string

req.http.host ~ "^www"

Matches if req.http.host starts with www.

req.url ~ "\.jpg$"

Matches if req.url ends with .jpg.

Multiple matches

req.url ~ "\.(png|jpg|css|js)$"

Matches if req.url ends with either .png, .jpg, .css, or .js.

req.url ~ "\.php(\?.*)?$"

Matches if req.url ends with .php, .php?foo=bar or .php?, but not .phpa.

req.url ~ "\.[abc]server$"

Matches if req.url ends with .aserver, .bserver or .cserver.

Matching wildcards

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.

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

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:

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:

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:

set req.http.Thing-I-Want = if(req.url ~ "(?i)\?.*some_query_arg=([^&]*)", re.group.1, "");

Replacing content

set req.http.host = regsub(req.http.host, "^www\.","");

Removes a leading www. from the host, if present.

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.:

Host: www.example.com ->
Host: www.example.com
api-test: api.example.com
Host: example.com ->
Host: example.com
api-test: example.com
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.

Back to Top