Master Nginx Regex and Location Matching: Rules, Priorities, and Real‑World Examples
This tutorial demonstrates how Nginx v1.23.2 processes regular expressions and location directives, explains the matching rules and priority hierarchy, and provides concrete configuration examples with code snippets and diagrams for each type of location prefix.
This article verifies Nginx v1.23.2 single‑node regular expression handling, location path matching rules, and their priority order.
<code>server {
listen 8081;
server_name 10.90.5.70;
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "http";
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_next_upstream error non_idempotent;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
</code>1. Regular expressions in Nginx
Nginx follows the standard Regular Expression syntax; the expression is introduced by a special character that tells Nginx to treat the following characters as a regex. Regular expressions can be used in
serverblocks or in
locationdirectives.
Common regex symbols
<code>^ : match start of the input string
$ : match end of the input string
. : match any single character except \n (use [\.\n] to include newline)
\d : match digits only
\w : match letters, digits, underscore or Chinese characters
\s : match any whitespace
\b : match word boundary
* : match preceding element zero or more times
+ : match preceding element one or more times
? : match preceding element zero or one time (equivalent to {0,1})
{n} : repeat exactly n times
{n,} : repeat n or more times
{n,m}: repeat between n and m times
[] : define a character class
[a-z] : match any lowercase letter a‑z
[a-zA-Z0-9] : match any alphanumeric character
() : group expression, e.g., (jpg|gif|swf)
| : logical OR
! : logical NOT (no AND operator in regex)
\\ : escape character
</code>2. Location path matching rules and priority
The
locationdirective sets the request URI handling. Its syntax is:
<code>location [ = | ~ | ~* | ^~ ] uri { ... }</code>Nginx first tries exact matches, then the longest literal prefix, then prefixes with
^~, followed by regular‑expression locations in the order they appear, and finally the generic
/block.
Official priority order (simplified):
Directives with the
=prefix that match exactly.
All remaining literal strings, longest match first; if the match uses
^~, stop searching.
Regular expressions, in the order of definition.
If a regex matched, use it; otherwise use the best literal match from step 2.
The five location prefix categories are:
= uri : exact match; rule is applied immediately.
~ regular : case‑sensitive regex match.
~* regular : case‑insensitive regex match.
^~ uri : literal prefix that disables further regex search.
url : plain prefix without any special symbol.
Priority relationship:
<code>(location =) > (location full path) > (location ^~) > (location ~*) > (location ~) > (location partial prefix) > (/)</code>Diagram of the matching flow:
Example 1 – No prefix (must start with pattern)
<code>server {
listen 8081;
server_name 127.0.0.1;
# No prefix, case‑sensitive, matches any URI that starts with /aaa
location /aaa {
default_type text/plain;
return 200 "access success aaa \n\r";
}
}
</code>Matches:
/aaa,
/aaa/,
/aaadef,
/aaa/def/,
/aaa?p1=TOM. Does not match
/Aaa. If the rule is written as
location /aaa/, only URIs beginning with
/aaa/are matched.
Example 2 – Exact match with =
<code>server {
listen 8081;
server_name 127.0.0.1;
# Exact match, case‑sensitive
location = /bbb {
default_type text/plain;
return 200 "access success bbb \n\r";
}
}
</code>Matches only
/bbband
/bbb?p1=TOM. Does not match
/bbb/,
/bbbcd, or
/Bbb.
Example 3 – Case‑sensitive regex ~
<code>server {
listen 8081;
server_name 127.0.0.1;
# Case‑sensitive regex: starts with /eee, ends with a word character
location ~^/eee\w$ {
default_type text/plain;
return 200 "access success. 000 Regular expression matched: eee \n\r";
}
}
</code>Matches:
/eeeb,
/eeeB,
/eee2. Does not match
/eee,
/Eee,
/eee/, etc.
Example 4 – Case‑insensitive regex ~*
<code>server {
listen 8081;
server_name 127.0.0.1;
# Case‑insensitive regex: starts with /ddd, ends with a word character
location ~*^/ddd\w$ {
default_type text/plain;
return 200 "access success. 111 Regular expression matched: ddd \n\r";
}
}
</code>Matches:
/dddb,
/dddB,
/ddd2,
/DddH. Does not match
/ddd,
/Ddd,
/ddd/, etc.
Example 5 – Prefix with ^~ (non‑regex, higher priority)
<code>server {
listen 8081;
server_name 127.0.0.1;
# ^~ disables further regex search for this prefix
location ^~ /fff {
default_type text/plain;
return 200 "access success. Non Regular expression matched: fff \n\r";
}
}
</code>Matches:
/fff,
/fff/,
/fffdef,
/fff/def/,
/fff?p1=TOM. Does not match
/Fffor
/pp/fff. If written as
location /fff/, only URIs beginning with
/fff/are matched.
Named location
<code># Example: internal redirect for 404 errors
error_page 404 = @fetch;
location @fetch {
proxy_pass http://fetch;
}
</code>Named locations (prefixed with
@) are used for internal redirects such as
error_pageor
try_files.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.