Nginx rewrite支持正则捕获组,用$1、$2等引用,仅在当前rewrite右侧及同级指令有效;可通过if+set或更推荐的map指令提前提取变量供复用。

Nginx 的 rewrite 指令支持正则表达式捕获,并可将捕获组作为变量在后续配置中使用,关键在于用圆括号 () 定义捕获组,然后通过 $1、$2 等引用。
基本语法:捕获并重写 URL
在 rewrite 中写正则时,Nginx 会自动把括号内的匹配内容赋给位置变量:
-
$1表示第一个()捕获的内容,$2是第二个,以此类推 - 这些变量只在当前
rewrite指令的右侧(replacement 部分)及同层级的后续指令(如return、set)中有效 - 注意:不支持命名捕获组(如
(?),只能用数字索引...)
在 rewrite 中直接使用捕获值
最常见用法是重写 URL 时插入捕获内容:
location /old/ {
rewrite ^/old/(\d+)/(\w+)$ /new/$2?id=$1 last;
}例如请求 /old/123/test → 重写为 /new/test?id=123。
其中 (\d+) 捕获到 123 → $1,(\w+) 捕获到 test → $2。
用 set 提取捕获值供其他地方复用
如果想在 rewrite 外使用捕获结果(比如日志、header、proxy_pass),需先用 set 保存:
location /api/ {
# 先匹配并捕获
if ($request_uri ~ ^/api/v(\d+)/users/(\d+)$) {
set $version $1;
set $user_id $2;
}
# 后续可用 $version 和 $user_id
proxy_set_header X-API-Version $version;
proxy_pass http://backend/users/$user_id;
}⚠️ 注意:if 在 location 中有局限(不推荐用于复杂逻辑),更稳妥的方式是结合 map 做预提取(见下一条)。
用 map 提前提取变量(推荐用于多处复用)
map 是 Nginx 中安全、高效提取正则变量的方式,定义在 http 块中:
http {
map $request_uri $api_version {
~^/api/v(\d+)/ $1;
default "";
}
map $request_uri $user_id {
~^/api/v\d+/users/(\d+) $1;
default "";
}
}
server {
location /api/ {
proxy_set_header X-Version $api_version;
proxy_set_header X-User-ID $user_id;
proxy_pass http://backend;
}
}这样所有匹配的请求都能稳定拿到提取值,且避免了 if + rewrite 的执行顺序陷阱。











