Regular expression captures
| Positional captures Named captures Preserving a positional capture |
Regular expressions used in the
location,
server_name,
if,
map,
and several other directives can contain captures.
A captured substring is referred to either positionally, as
“$1”...“$9”, or by name.
The two forms differ in how long the captured value stays available.
Everything described below also applies to the server_name and map directives of the stream module.
Positional captures
Positional captures are numbered in the order the capturing groups appear in a regular expression:
location ~ ^/images/(.*)\.([a-z]+)$ {
# for the "/images/cats/tom.jpg" request
# $1 is "cats/tom" and $2 is "jpg"
}
Positional captures are not variables. They form a single set of values shared by all these directives while a request or a connection is processed. A successful match replaces the whole set, and an unsuccessful match may clear it. The values therefore remain available only until the next match, which may happen in an unrelated directive.
A match may also happen implicitly. Since variables are evaluated only when they are used, referring to a map variable with regular expressions in source values matches them at that moment, and a successful match replaces the positional captures:
map $uri $mapped {
~^/(?<first>[^/]+)/ $first;
}
location ~ ^/images/(.*)$ {
set $name $1; # "cats/tom.jpg"
set $m $mapped; # "images"
set $name2 $1; # "images", not "cats/tom.jpg"
}
Named captures
A capture can be given a name:
location ~ ^/images/(?<name>.*)\.(?<ext>[a-z]+)$ {
...
}
Named captures create ordinary nginx variables, in this case
$name and $ext.
Their values are not replaced when another regular expression is matched,
unless it uses the same capture name.
This makes named captures the preferred way to pass a captured value
to a directive other than the one that has performed the match.
The PCRE library supports named captures using the following syntax:
?<name>Perl compatible syntax ?'name'Perl compatible syntax ?P<name>Python compatible syntax
Preserving a positional capture
If a positional capture is needed later and cannot be replaced with a named one, its value should be copied into a variable right after the match, using the set directive (set in the stream module):
location ~ ^/images/(.*)$ {
set $name $1;
}