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