nginx中server_name精准匹配正则需以~或~*开头、用^和$锚定首尾、转义.等特殊字符,并置于通配符server块之前以防优先级被截胡。

要用正则表达式在 server_name 中实现精准匹配,核心是:用 ~ 或 ~* 开头、严格锚定首尾、正确转义特殊字符,并确保它不被更高优先级的匹配“截胡”。
必须以 ~ 或 ~* 开头
Nginx 不会把带 .、^、$ 的字符串自动识别为正则——必须显式声明。否则会被当作精确字符串处理。
-
正确:
server_name ~^api\.example\.com$; -
错误(当成精确匹配):
server_name ^api\.example\.com$;(缺少~,Nginx 会找字面值为^api.example.com$的域名)
用 ^ 和 $ 锚定整个 Host 头
正则默认是“包含匹配”,不加锚点会导致意外命中。比如 ~api\.example\.com 会匹配 myapi.example.com 和 api.example.com.vip,这不是精准匹配。
- 加上
^确保从 Host 开头匹配 - 加上
$确保到 Host 结尾结束 - 例如:
server_name ~^www\d{2}\.example\.com$;只匹配www01.example.com、www99.example.com,不匹配www01.example.com.cn或sub.www01.example.com
特殊字符必须转义
域名里的点号 . 在正则中表示“任意字符”,必须写成 \.;连字符 - 在方括号内要放最前或最后才安全;如果正则含 {、}、空格等,必须用双引号包裹整条语句。
-
server_name ~^test-[a-z]+\.(example|demo)\.com$;→ 错误:连字符未转义且括号未引号 -
server_name "~^test-[a-z]+\.(example|demo)\.com$";→ 正确:加引号 + 转义点号
注意匹配优先级,避免被通配符抢走
即使你写了精准正则,如果配置块里同时存在 *.example.com,而请求是 api.example.com,Nginx 会优先选通配符(因通配符优先级高于正则),导致正则根本不会生效。
- 解决办法:把正则所在的
server块放在通配符块之前,或干脆拆开——让精准域名走独立server块(用精确匹配),复杂规则再用正则兜底 - 验证方式:
nginx -t检查语法,再用curl -H "Host: api.example.com" http://127.0.0.1看是否进入预期 server 块











