nginx rewrite正则匹配请求uri路径部分(不含协议、域名和查询参数),需用pcre语法精确锚定、正确处理编码、合理使用捕获组与变量,并依flag控制流程;错误易致404、循环重定向或失效。

Nginx 中 rewrite 规则的正则表达式不是简单匹配路径字符串,而是作用于请求 URI(不包含协议、域名和查询参数的部分),需结合 PCRE 语法、捕获组、变量引用及 flag 行为综合使用。写错正则或忽略执行顺序,常导致 404、循环重定向或规则不生效。
正则表达式匹配对象与边界控制
rewrite 的 regex 只匹配 location 后的 URI 路径部分(例如 http://example.com/a/b/c?x=1 中只匹配 /a/b/c)。默认不自动锚定首尾,因此:
- 用
^/old/(\w+)$精确匹配以/old/开头、后跟一个单词字符并结尾的路径,避免误中/oldly/abc - 避免写成
/old/(\w+)—— 它会匹配/old/abc/def中的/old/abc,造成截断错误 - 中文或特殊字符路径需注意编码:URI 已是百分号编码形式(如
/文章/→/%E6%96%87%E7%AB%A0/),正则应按编码后字符串编写,或改用$request_uri变量配合if判断
捕获组与变量替换的实际用法
括号 () 创建捕获组,可在 replacement 中用 、 引用;同时 Nginx 内置大量变量(如 $host、$args)可参与拼接:
-
rewrite ^/user/(\d+)/profile$ /u/$1/info permanent;→ 将/user/123/profile永久跳转到/u/123/info -
rewrite ^/blog/(.*)$ https://blog.example.com/$1?$args redirect;→ 带完整参数跳转子域,$args保留原始查询串 - 多个捕获时注意嵌套顺序:
^/api/v(\d+)/([a-z]+)/(\d+)$中$1=v1、$2=users、$3=42
flag 对重写流程的决定性影响
flag 不只是“跳不跳”,它直接改变 Nginx 的请求处理流程:
-
last:重写后立即用新 URI 重新进入server → location匹配流程(相当于内部重试),适合路径改写后仍由本机服务(如前端路由 fallback) -
break:重写后不再查找新 location,直接在当前 location 内继续执行后续指令(如root、try_files),适合静态资源路径映射 -
redirect和permanent:强制返回 302 或 301 响应,客户端地址栏可见跳转,适用于 SEO 迁移或域名变更 - 慎用
if块内 rewrite:if 是伪指令,其内部 rewrite 行为受限制,且易引发重复执行或逻辑混乱,优先用map或 location 分流替代
调试与避坑要点
正则行为不易直观验证,上线前必须验证:
- 开启 rewrite 日志:
rewrite_log on;(需搭配error_log ... notice;),查看匹配是否触发、捕获是否正确 - 测试循环风险:Nginx 对 rewrite 循环上限为 10 次,超限返回 500,典型诱因是
last规则未终结或 location 匹配逻辑闭环 - 区分大小写:PCRE 默认区分大小写,如需忽略,正则开头加
(?i),例如^(?i)/OLD/(\w+)$ - 不要在 rewrite 中尝试匹配 query string(如
?id=1)——它不在匹配范围内;要用$args或$request_uri单独判断











