Nginx 中如何利用正则表达式捕获路径参数

作者:袖梨 2026-08-20

<p>Nginx location 支持正则捕获,需用 ~ 或 ~* 启用,捕获组 $1、$2 或命名捕获 $name 仅在当前 location 内有效,可用于 rewrite、proxy_pass 等指令,但不可跨块或 if 外引用。</p>

Nginx 支持在 location 指令中使用正则表达式,并通过捕获组(capture groups)提取路径中的动态参数,再在后续指令(如 rewriteproxy_pass 或变量引用)中复用。关键在于正确书写带括号的正则、理解捕获变量命名规则,并注意作用域限制。

location 中用 ~* 或 ~ 定义正则匹配

必须使用带波浪线的修饰符启用正则匹配:~(区分大小写)或 ~*(不区分大小写)。普通前缀匹配(location /api/)不支持捕获。

  1. location ~ ^/user/(d+)/profile$ { ... } —— 匹配 /user/123/profile$1 值为 123
  2. location ~* ^/product/([a-z0-9-]+)/(d+)$ { ... } —— 不区分大小写,捕获两段,分别存为 $1$2
  3. 注意:正则匹配优先级高于前缀匹配,但低于精确匹配(=),且同级中按配置顺序生效

捕获变量 $1、$2 … 只在当前 location 内有效

正则括号内的内容会按从左到右顺序赋值给 $1$2 等变量,但这些变量仅在该 location 块内可用,不能跨块传递。

  1. 可在 rewrite 中重写 URL:rewrite ^/post/(d+) /blog?id=$1 last;
  2. 可在 proxy_pass 中拼接后端地址:proxy_pass http://backend/api/v1/user/$1;
  3. 不可在 if 外部直接引用(if 内部也受限,建议避免嵌套 if

命名捕获(Nginx 1.11.2+)更清晰易读

支持 (?<name>...) 语法,用 $name 引用,提升可维护性:

  1. location ~ ^/api/(?<version>vd+)/(?<resource>w+)/(?<id>d+)$ {
  2. 后续可用 $version$resource$id,比如:proxy_pass http://api/$version/$resource/$id;
  3. 命名捕获与数字捕获可混用,但推荐统一用命名方式减少出错

实际配置示例:RESTful 路由转发

/api/v2/users/456 映射到后端 http://internal/users/456?version=v2

location ~ ^/api/(?<ver>vd+)/(?<res>w+)/(?<uid>d+)$ {proxy_set_header Host $host;proxy_pass http://backend/$res/$uid?version=$ver;}

注意:proxy_pass 若含 URI 部分(如 /users/$uid),会替换整个原始路径;若只写上游地址(如 http://backend),则自动透传原始 URI。

相关文章

精彩推荐