Regex
Regex location matching lets NGINX choose a location block using a regular expression applied to the request URI.
It is used when:
- Paths follow patterns (file extensions, versions, IDs)
- You need case-insensitive matching
- Prefix matching is not flexible enough
Regex Location Modifiers
| Modifier | Meaning |
|---|---|
~ | Case-sensitive regex match |
~* | Case-insensitive regex match |
location ~ pattern {
...
}
location ~* pattern {
...
}
patternis a PCRE regular expression- Applied to the URI only (query string ignored)
- No quotes required
Case-Sensitive Regex (~)
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
}
What it matches
| URI | Match? |
|---|---|
/index.php | Yes |
/test.php | Yes |
/TEST.PHP | No |
Because matching is case-sensitive.
Case-Insensitive Regex (~*)
location ~* \.(jpg|jpeg|png|gif)$ {
expires 30d;
}
What it matches
| URI | Match? |
|---|---|
/img/a.jpg | Yes |
/img/A.JPG | Yes |
/img/b.PnG | Yes |
Location Matching Order (Critical!)
NGINX evaluates locations in this order:
- Exact match (
location =) - Prefix match (longest match wins)
- Regex match (first match wins)
- Default (
location /)
Regex locations are evaluated in the order they appear in the config.
Prefix vs Regex (Who Wins?)
location /images/ {
root /var/www/images;
}
location ~ \.jpg$ {
root /var/www/jpg;
}
- Request:
/images/photo.jpg - Result:
- Prefix
/images/matches - Regex
\.jpg$also matches - Regex wins, because it’s checked after prefix
- Prefix
Prevent Regex Override with ^~
location ^~ /images/ {
root /var/www/images;
}
- Prefix match is selected
- Regex is skipped entirely
Regex Order Matters (First Match Wins)
location ~ \.php$ {
return 200 "Generic PHP";
}
location ~ /admin/.*\.php$ {
return 403;
}
- Request:
/admin/test.php - Result:
- First regex matches
- Access is allowed unintentionally
Correct order
location ~ /admin/.*\.php$ {
return 403;
}
location ~ \.php$ {
return 200 "Generic PHP";
}
Using Capture Groups in Regex Locations
location ~ ^/api/v(\d+)/ {
proxy_pass http://api_v$1_backend;
}
- Request:
/api/v2/users$1 = 2- Proxied to
api_v2_backend
Regex with rewrite
location ~ ^/old/(.*)$ {
rewrite ^/old/(.*)$ /new/$1 permanent;
}
Common Use Cases
- File extension handling
location ~* \.(css|js)$ {
expires 7d;
}
- Blocking sensitive files
location ~* \.(env|log|bak)$ {
deny all;
}
- Language or version routing
location ~ ^/(en|fr|de)/ {
root /var/www/lang;
}
Regex Matching Details You Must Know
- Regex applies to normalized URI
- Query string (
?x=1) is ignored - Use
^and$for precision - Avoid overly complex patterns (performance)