<p>Nginx rewrite规则中特殊字符需按上下文正确转义:正则部分遵循PCRE规则,元字符如. ? * + ( ) [ ] { } | ^ $ 等须加反斜杠;字符串字面量中反斜杠会被Nginx额外解析,$需写成$$,?在替换末尾控制query string传递。</p>

Nginx 的 rewrite 规则中,特殊字符必须正确转义,否则会导致语法错误、匹配失败或意外重定向。核心原则是:**在正则表达式上下文中,Nginx 使用 PCRE(Perl 兼容正则),所以转义规则遵循 PCRE;而在非正则的字符串字面量(如 return 或 set)中,Nginx 自身会做一次解析,需额外注意反斜杠处理。**
正则匹配部分(rewrite 第二个参数)要按 PCRE 转义
rewrite 指令的格式是:rewrite <正则> <替换> [flag];。其中第一个参数是 PCRE 正则,所有正则元字符都需转义才能表示字面意义:
-
点号
.→ 写成\.(否则匹配任意字符) -
问号
?→ 写成\?(否则表示前一项可选) -
星号
*→ 写成\*(否则表示前一项重复 0 次或多次) -
加号
+→ 写成\+(否则表示前一项重复 1 次或多次) -
括号
( )、方括号[ ]、花括号{ }、竖线|、脱字符^、美元符$等,只要想匹配字面值,都要加反斜杠
例如:把 /api/v1.2/test?name=abc 重写为 /v1/test?name=abc,需转义点和问号:
替换部分(rewrite 第三个参数)中变量和特殊符号要小心
替换字符串支持 、 等捕获组,也支持 $host、$request_uri 等内置变量。注意:
- 如果替换内容含
$字符本身(非变量),必须写成$$,否则 Nginx 会尝试解析为变量 - 问号
?在替换串末尾表示“不带原始 query string”,但若你想保留原始参数又手动拼接,需显式写出?—— 它不需要转义,但位置很关键 - 斜杠
/在路径中是普通字符,一般不用转义;但若出现在正则中作为分隔符(比如你用~开头的正则),则需避免冲突,建议统一用~*并换分隔符(如用~* "^/a\.b/c$")
location 中的正则与 rewrite 共享同一套转义逻辑
如果你在 location ~ ^/static/\d+\.(js|css|png)$ 这类正则 location 里嵌套 rewrite,点、括号、竖线等同样要转义:
rewrite ^/static/(.+)$ /cdn/$1 break;
}
这里 \. 是必须的,| 在括号内属于正则语法,不需额外转义(但放在括号外就需 \|)。
调试技巧:用 nginx -t 和 error_log 验证
写完 rewrite 后务必运行 nginx -t 检查语法。若匹配异常,开启 debug 日志:
rewrite_log on;
日志会输出每次匹配过程和重写结果,方便定位是正则没命中,还是转义错了导致模式失效。


















