VCL regular expression cheat sheet

Regular expressions (regex) let you match patterns in URLs, headers, and other request data. Fastly VCL uses Perl Compatible Regular Expression (PCRE) syntax. This cheat sheet provides quick reference examples for common regular expression patterns used in Fastly VCL.

HINT: Regular expressions are case sensitive by default. To disable case sensitivity, add (?i) to the start of your expression.

Basic matching

This pattern matches only if req.url is exactly /phrase:

req.url == "/phrase"

This pattern matches phrase anywhere:

req.url ~ "phrase"

This pattern matches URLs that do not end with .jpg:

req.url !~ "\.jpg$"

This is called an inverse match or negation.

IMPORTANT: Special regex characters (. * + ? ^ $ { } [ ] ( ) | \) need to be escaped with a backslash (\) to match literally. Forward slashes (/) do not need to be escaped. For example, req.http.host ~ "example.com" matches both example.com AND exampleXcom. You would use req.http.host ~ "example\.com" to match only example.com.

Matching at the beginning or end of a string

This pattern matches if req.http.host starts with www:

req.http.host ~ "^www"

This pattern matches if req.url ends with .jpg:

req.url ~ "\.jpg$"

Multiple matches

This pattern matches if req.url ends with either .png, .jpg, .css, or .js:

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

This pattern matches if req.url ends with .php, .php?foo=bar or .php?, but not .phpa:

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

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

This pattern matches if req.url ends with .aserver, .bserver or .cserver:

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

Matching wildcards

This pattern 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$"

This pattern matches jp followed by 0 or more random characters ending with the letter g (jpeg, jpg, and jpeeeeg all match):

req.url ~ "jp.*g$"

Capturing matches

Use capture groups (parentheses in your regex pattern) to extract specific parts of a URL or header for reuse elsewhere in your VCL logic. Access captured groups using re.group.1 for the first capture, re.group.2 for the second, and continuing numerically for additional captures. The re.group.0 variable always contains the entire matched string.

This example shows how to capture multiple groups from a string:

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 'ccccc'
}

Instead of using regsub to extract a query parameter like this:

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

Use regsub and regsuball to modify URLs, headers, or other request/response data.

This example removes a leading www. from the host, if present:

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

This example sets the api-test header to contain the host-header, but replaces a leading www. with api.:

set req.http.api-test = regsub(req.http.host, "^www\.","api.");
Host: www.example.com ->
Host: www.example.com
api-test: api.example.com
Host: example.com ->
Host: example.com
api-test: example.com

This example 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:

set req.url = regsuball(req.url, "/+", "/");