nginx rewrite支持正则捕获分组,用()定义、$1/$2引用,仅在当前指令生效;需转义特殊字符,最多9组,变量不跨指令传递,调试需开启rewrite_log和error_log。

Nginx 的 rewrite 指令支持正则表达式捕获分组,用圆括号 () 定义,匹配后可通过 $1、$2 等变量引用。关键在于:正则必须写在 rewrite 第二个参数(即重写目标)中,且仅对当前指令生效。
捕获分组的基本写法
在 rewrite 的正则部分用 () 包裹要提取的内容,Nginx 会按从左到右顺序编号为 $1、$2… 最多支持 9 个捕获组。
-
rewrite ^/article/(\d+)/(.+)$ /post.php?id=$1&title=$2 last;匹配/article/123/nginx-tutorial→ 重写为/post.php?id=123&title=nginx-tutorial - 非贪婪或特殊字符需转义:如匹配点号
\.、问号\?,否则会被当作正则元字符处理 - 注意:只有被
rewrite指令成功匹配的请求才会触发捕获,未匹配则跳过该规则
捕获内容参与条件判断
可在 if 块中结合 等变量做逻辑判断,但要注意 if 在 location 中有局限性,推荐优先用 map 或直接 rewrite 处理。
-
if ($1 ~ "^\d+$") { rewrite ^/(.*)$ /numeric/$1? permanent; }前提是外层 rewrite 已捕获$1,否则$1为空 - 更稳妥的方式是把判断逻辑放进 rewrite 正则本身,例如:
rewrite ^/user/(\d+)$ /profile?id=$1 last;,隐含要求第一组必须是数字
嵌套括号与转义注意事项
多层括号按左括号出现顺序编号,转义括号 \( 不计入捕获组;重复使用同一组变量时,以最后一次匹配为准。
-
rewrite ^/api/v(\d)/(\w+)/(.*)$ /v$1/$2/api/$3 last;/api/v2/user/list→/v2/user/api/list,$1是v后的数字 - 想匹配字面量括号,写成
\(和\),它们不产生$n变量 - 避免过度嵌套,Nginx 对正则复杂度有限制,太深可能报
PCRE limit错误
常见陷阱和调试技巧
捕获分组看似简单,但容易因作用域或匹配失败导致变量为空,引发 404 或重写错误。
-
$1等变量只在当前rewrite指令内部有效,不能跨指令传递(比如不能在下一个rewrite里直接用上一条的$1) - 开启
error_log /path/to/log notice;并设置日志级别为notice或info,配合rewrite_log on;查看重写过程 - 用
curl -I或浏览器开发者工具确认实际跳转 URL,比单纯看配置更可靠











