To use a regular expression in an NGINX map, prefix its pattern with ~ for case-sensitive matching or ~* for case-insensitive matching. Declare the map in the http context, order regex rules from specific to general, and set an explicit default for unmatched values.
What an NGINX map does
The map directive creates a variable whose value depends on one or more source variables. For example, a map can inspect a request URI and choose a routing value. The NGINX map module documentation specifies that maps belong in the http context; the resulting variable is evaluated only when it is used.
http {
map $request_uri $route {
default backend_default;
~^/api/(?<version>v[0-9]+)/ backend_$version;
~*^/legacy/ backend_legacy;
}
}
Here, $request_uri is the input and $route is the variable assigned by the map. The first regex recognizes an API path and captures a version such as v2; the second recognizes /legacy/ without regard to case. The literal default entry handles values not matched by another entry.
How to choose a map key or pattern
A map can use exact string keys, hostname masks, or regular expressions. Ordinary string keys are matched case-insensitively. Regexes are useful when a value follows a pattern or needs captures; prefer an exact key or hostname mask when it expresses the condition clearly, since those categories take precedence over regexes.
#1 Best Overall
| Entry type | Example | Matching behavior | Precedence |
|---|---|---|---|
| Exact string | api.example.com |
Matches that string value; ordinary string keys are case-insensitive. | First, unless the exact entry uses a mask. |
| Hostname mask | *.example.com or .example.com |
With hostnames;, matches subdomains; the leading-dot form combines the bare domain and its subdomains. |
After exact strings; longer prefix masks precede longer suffix masks. |
| Regular expression | ~^/api/ or ~*^/legacy/ |
Tests a regex against the source value; ~ is case-sensitive and ~* is case-insensitive. |
After exact strings and hostname masks; first matching regex in file order wins. |
| Default | default fallback; |
Applies when no other entry matches. | Last fallback. |
Which map rule wins?
NGINX checks applicable entry categories in a fixed order, not simply from top to bottom across the entire map. Exact string values without masks win first. Next come the longest hostname prefix mask, then the longest suffix mask. Regex entries are then checked in their written order, and default applies if none match.
Consequently, moving a regex above another regex can change the result, but it cannot make that regex outrank a matching exact key or hostname mask. Put specific regexes before broad ones so a catch-all pattern does not capture values intended for a later, narrower rule.
How to match hostnames
For hostname masks, put hostnames; before the map entries and use $host (or another hostname source) as the input. A mask such as *.example.com matches subdomains; .example.com combines the bare domain with its subdomains.
map $host $tenant {
hostnames;
default unknown;
.example.com example;
~^(?<id>[0-9]+).example.net$ tenant_$id;
}
In this example, the hostname mask is considered before the regex because hostname masks have a higher precedence category. The regex captures the numeric label in a hostname such as 42.example.net.
Rank #3
How to capture and reuse part of a value
A map regex can define named captures, such as (?<file>...), or positional captures. The map result may combine literal text and variables, so a captured value can be inserted into the result.
map $uri $asset {
default /assets/default;
~^/img/(?<file>[a-z0-9_-]+).png$ /assets/$file.png;
}
A request URI like /img/logo-2.png matches the regex and yields /assets/logo-2.png. Named captures are generally safer when other regex directives may run: a successful map regex replaces positional captures $1 through $9 from an earlier regex. NGINX’s server names documentation also warns that positional captures can be overwritten when other regex directives execute.
How to make map regexes reliable
- Anchor full-value tests. Use
^at the start and$at the end when the whole input must match, rather than just a substring. - Escape literal dots. Write
.when a dot should match a period rather than any character. - Quote braces when needed. If a regex contains
{or}and NGINX could parse them as configuration syntax, quote the pattern. - Keep ordering intentional. Check regexes from most specific to broadest, because the first matching regex wins within the regex category.
- Give unmatched inputs a deliberate result. Without a
default, an unmatched map returns an empty string, which may be indistinguishable from an intentionally empty result.
NGINX regex directives use PCRE-compatible syntax. Check compatibility against the NGINX release deployed in your environment; the module documentation notes historical version additions for regex sources and case-insensitive matching.
Why a map regex may not match
- The expression is missing its marker. A regex entry needs the
~or~*prefix; without it, the entry is not marked as a regex. - Case differs. Use
~*when letter case should not matter. The case-insensitive treatment of ordinary string keys does not make a regex case-insensitive. - The pattern is too broad or too narrow. Add anchors for a whole-value test, and escape dots that are meant literally.
- A higher-precedence entry already matches. An exact key or hostname mask is evaluated before regexes.
- An earlier regex wins first. Reorder regex entries if a broad pattern is catching a value before the intended specific pattern.
- A hostname mask lacks its declaration. Include
hostnames;before hostname masks such as*.example.com. - The map result is empty. If no entry matches and there is no
default, the result is an empty string.
When these rules apply to stream maps
For NGINX stream maps, the stream map module documentation confirms the same core regex and precedence rules. Use the map module appropriate to the configuration context rather than assuming an HTTP map can be declared in a stream context.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

